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#define GET_CALLING_CONV_IMPL
1859#include "SystemZGenCallingConv.inc"
1863 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1869 Type *ToType)
const {
1932 if (BitCastToType == MVT::v2i64)
1959 MVT::Untyped,
Hi,
Lo);
1983 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1985 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1996 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
1997 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2008template <
class ArgTy>
2011 MVT &PartVT,
unsigned &NumParts) {
2012 if (!Args[
I].Flags.isSplit())
2016 PartVT = ArgLocs[
I].getValVT();
2018 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2019 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2020 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2022 if (Args[PartIdx].Flags.isSplitEnd())
2046 unsigned NumFixedGPRs = 0;
2047 unsigned NumFixedFPRs = 0;
2048 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2061 RC = &SystemZ::GR32BitRegClass;
2065 RC = &SystemZ::GR64BitRegClass;
2069 RC = &SystemZ::FP16BitRegClass;
2073 RC = &SystemZ::FP32BitRegClass;
2077 RC = &SystemZ::FP64BitRegClass;
2081 RC = &SystemZ::FP128BitRegClass;
2090 RC = &SystemZ::VR128BitRegClass;
2104 if (Subtarget.isTargetXPLINK64()) {
2107 ArgSPOffset += XPRegs.getCallFrameSize();
2118 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2122 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2136 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2139 unsigned PartOffset = Ins[
I].PartOffset;
2144 assert(PartOffset &&
"Offset should be non-zero.");
2151 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2157 Subtarget.getSpecialRegisters());
2163 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2168 if (IsVarArg && Subtarget.isTargetELF()) {
2181 int64_t RegSaveOffset =
2196 &SystemZ::FP64BitRegClass);
2208 if (Subtarget.isTargetXPLINK64()) {
2213 Subtarget.getSpecialRegisters());
2214 MRI.
addLiveIn(Regs->getADARegister(), ADAvReg);
2226 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2233 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2235 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2242 unsigned Offset,
bool LoadAdr =
false) {
2265 bool LoadAddr =
false;
2287 unsigned ADADelta = 0;
2288 unsigned EPADelta = 8;
2294 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2295 G->getGlobal()->hasPrivateLinkage());
2302 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2348 if (Subtarget.isTargetXPLINK64())
2352 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2356 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2375 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2383 unsigned NumParts = 1;
2387 SlotVT = Outs[
I].VT;
2394 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2397 assert(Outs[
I].PartOffset == 0);
2398 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2401 unsigned PartOffset = Outs[
I].PartOffset;
2407 assert(PartOffset &&
"Offset should be non-zero.");
2409 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2411 ArgValue = SpillSlot;
2428 if (!StackPtr.getNode())
2435 else if (VA.
getLocVT() == MVT::f16)
2448 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2452 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2458 if (!MemOpChains.
empty())
2466 if (Subtarget.isTargetXPLINK64()) {
2471 ->getAddressOfCalleeRegister();
2474 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2481 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2484 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2485 }
else if (IsTailCall) {
2488 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2493 for (
const auto &[Reg,
N] : RegsToPass) {
2500 Ops.push_back(Chain);
2501 Ops.push_back(Callee);
2505 for (
const auto &[Reg,
N] : RegsToPass)
2510 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2511 assert(Mask &&
"Missing call preserved mask for calling convention");
2516 Ops.push_back(Glue);
2525 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2535 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2542 VA.getLocVT(), Glue);
2559 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2561 Args.reserve(
Ops.size());
2567 Entry.IsZExt = !Entry.IsSExt;
2568 Args.push_back(Entry);
2579 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2590 const Type *RetTy)
const {
2593 for (
auto &Out : Outs)
2594 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2598 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2599 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2611 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2619 if (RetLocs.
empty())
2620 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2629 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2651 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2658 unsigned &CCValid) {
2659 unsigned Id =
Op.getConstantOperandVal(1);
2661 case Intrinsic::s390_tbegin:
2662 Opcode = SystemZISD::TBEGIN;
2666 case Intrinsic::s390_tbegin_nofloat:
2667 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2671 case Intrinsic::s390_tend:
2672 Opcode = SystemZISD::TEND;
2685 unsigned Id =
Op.getConstantOperandVal(0);
2687 case Intrinsic::s390_vpkshs:
2688 case Intrinsic::s390_vpksfs:
2689 case Intrinsic::s390_vpksgs:
2690 Opcode = SystemZISD::PACKS_CC;
2694 case Intrinsic::s390_vpklshs:
2695 case Intrinsic::s390_vpklsfs:
2696 case Intrinsic::s390_vpklsgs:
2697 Opcode = SystemZISD::PACKLS_CC;
2701 case Intrinsic::s390_vceqbs:
2702 case Intrinsic::s390_vceqhs:
2703 case Intrinsic::s390_vceqfs:
2704 case Intrinsic::s390_vceqgs:
2705 case Intrinsic::s390_vceqqs:
2706 Opcode = SystemZISD::VICMPES;
2710 case Intrinsic::s390_vchbs:
2711 case Intrinsic::s390_vchhs:
2712 case Intrinsic::s390_vchfs:
2713 case Intrinsic::s390_vchgs:
2714 case Intrinsic::s390_vchqs:
2715 Opcode = SystemZISD::VICMPHS;
2719 case Intrinsic::s390_vchlbs:
2720 case Intrinsic::s390_vchlhs:
2721 case Intrinsic::s390_vchlfs:
2722 case Intrinsic::s390_vchlgs:
2723 case Intrinsic::s390_vchlqs:
2724 Opcode = SystemZISD::VICMPHLS;
2728 case Intrinsic::s390_vtm:
2729 Opcode = SystemZISD::VTM;
2733 case Intrinsic::s390_vfaebs:
2734 case Intrinsic::s390_vfaehs:
2735 case Intrinsic::s390_vfaefs:
2736 Opcode = SystemZISD::VFAE_CC;
2740 case Intrinsic::s390_vfaezbs:
2741 case Intrinsic::s390_vfaezhs:
2742 case Intrinsic::s390_vfaezfs:
2743 Opcode = SystemZISD::VFAEZ_CC;
2747 case Intrinsic::s390_vfeebs:
2748 case Intrinsic::s390_vfeehs:
2749 case Intrinsic::s390_vfeefs:
2750 Opcode = SystemZISD::VFEE_CC;
2754 case Intrinsic::s390_vfeezbs:
2755 case Intrinsic::s390_vfeezhs:
2756 case Intrinsic::s390_vfeezfs:
2757 Opcode = SystemZISD::VFEEZ_CC;
2761 case Intrinsic::s390_vfenebs:
2762 case Intrinsic::s390_vfenehs:
2763 case Intrinsic::s390_vfenefs:
2764 Opcode = SystemZISD::VFENE_CC;
2768 case Intrinsic::s390_vfenezbs:
2769 case Intrinsic::s390_vfenezhs:
2770 case Intrinsic::s390_vfenezfs:
2771 Opcode = SystemZISD::VFENEZ_CC;
2775 case Intrinsic::s390_vistrbs:
2776 case Intrinsic::s390_vistrhs:
2777 case Intrinsic::s390_vistrfs:
2778 Opcode = SystemZISD::VISTR_CC;
2782 case Intrinsic::s390_vstrcbs:
2783 case Intrinsic::s390_vstrchs:
2784 case Intrinsic::s390_vstrcfs:
2785 Opcode = SystemZISD::VSTRC_CC;
2789 case Intrinsic::s390_vstrczbs:
2790 case Intrinsic::s390_vstrczhs:
2791 case Intrinsic::s390_vstrczfs:
2792 Opcode = SystemZISD::VSTRCZ_CC;
2796 case Intrinsic::s390_vstrsb:
2797 case Intrinsic::s390_vstrsh:
2798 case Intrinsic::s390_vstrsf:
2799 Opcode = SystemZISD::VSTRS_CC;
2803 case Intrinsic::s390_vstrszb:
2804 case Intrinsic::s390_vstrszh:
2805 case Intrinsic::s390_vstrszf:
2806 Opcode = SystemZISD::VSTRSZ_CC;
2810 case Intrinsic::s390_vfcedbs:
2811 case Intrinsic::s390_vfcesbs:
2812 Opcode = SystemZISD::VFCMPES;
2816 case Intrinsic::s390_vfchdbs:
2817 case Intrinsic::s390_vfchsbs:
2818 Opcode = SystemZISD::VFCMPHS;
2822 case Intrinsic::s390_vfchedbs:
2823 case Intrinsic::s390_vfchesbs:
2824 Opcode = SystemZISD::VFCMPHES;
2828 case Intrinsic::s390_vftcidb:
2829 case Intrinsic::s390_vftcisb:
2830 Opcode = SystemZISD::VFTCI;
2834 case Intrinsic::s390_tdc:
2835 Opcode = SystemZISD::TDC;
2848 unsigned NumOps =
Op.getNumOperands();
2851 Ops.push_back(
Op.getOperand(0));
2853 Ops.push_back(
Op.getOperand(
I));
2855 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2869 unsigned NumOps =
Op.getNumOperands();
2875 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2876 "Unhandled intrinsic with f16 operand.");
2879 Ops.push_back(CurrOper);
2893 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2894 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2895 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2921 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2924 int64_t
Value = ConstOp1->getSExtValue();
2940 if (!
C.Op0.hasOneUse() ||
2947 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2948 if ((NumBits != 8 && NumBits != 16) ||
2949 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2955 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2958 uint64_t Mask = (1 << NumBits) - 1;
2961 int64_t SignedValue = ConstOp1->getSExtValue();
2968 }
else if (NumBits == 8) {
2994 if (
C.Op0.getValueType() != MVT::i32 ||
2995 Load->getExtensionType() != ExtType) {
2997 Load->getBasePtr(), Load->getPointerInfo(),
2998 Load->getMemoryVT(), Load->getAlign(),
2999 Load->getMemOperand()->getFlags());
3005 if (
C.Op1.getValueType() != MVT::i32 ||
3006 Value != ConstOp1->getZExtValue())
3016 if (Load->getMemoryVT() == MVT::i8)
3019 switch (Load->getExtensionType()) {
3037 if (
C.Op0.isMachineOpcode() &&
3038 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3042 if (
C.Op0.getValueType() == MVT::i128)
3044 if (
C.Op0.getValueType() == MVT::f128)
3056 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3085 unsigned Opcode0 =
C.Op0.getOpcode();
3092 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3107 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3108 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3130 if (C1 && C1->isZero()) {
3149 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3152 if (C1 && C1->getZExtValue() == 32) {
3153 SDValue ShlOp0 =
C.Op0.getOperand(0);
3172 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3175 C.Op1->getAsZExtVal() == 0) {
3177 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3178 C.Op0.getValueSizeInBits().getFixedValue()) {
3179 unsigned Type = L->getExtensionType();
3182 C.Op0 =
C.Op0.getOperand(0);
3198 if (
C.Opcode != SystemZISD::ICMP)
3208 if (!
C.Op1.isMachineOpcode() ||
3209 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3214 C.Opcode = SystemZISD::CMP_STACKGUARD;
3225 uint64_t Amount = Shift->getZExtValue();
3226 if (Amount >=
N.getValueSizeInBits())
3241 unsigned ICmpType) {
3242 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3264 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3270 if (EffectivelyUnsigned && CmpVal <
Low) {
3278 if (CmpVal == Mask) {
3284 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3290 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3298 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3304 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3333 if (
C.Op0.getValueType() == MVT::i128) {
3339 if (Mask && Mask->getAPIntValue() == 0) {
3340 C.Opcode = SystemZISD::VTM;
3357 uint64_t CmpVal = ConstOp1->getZExtValue();
3364 NewC.Op0 =
C.Op0.getOperand(0);
3365 NewC.Op1 =
C.Op0.getOperand(1);
3369 MaskVal = Mask->getZExtValue();
3389 MaskVal = -(CmpVal & -CmpVal);
3398 unsigned NewCCMask, ShiftVal;
3402 (MaskVal >> ShiftVal != 0) &&
3403 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3405 MaskVal >> ShiftVal,
3409 MaskVal >>= ShiftVal;
3413 (MaskVal << ShiftVal != 0) &&
3414 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3416 MaskVal << ShiftVal,
3420 MaskVal <<= ShiftVal;
3429 C.Opcode = SystemZISD::TM;
3431 if (Mask && Mask->getZExtValue() == MaskVal)
3436 C.CCMask = NewCCMask;
3442 if (
C.Opcode != SystemZISD::ICMP)
3444 if (
C.Op0.getValueType() != MVT::i128)
3455 Src = Src.getOperand(0);
3458 unsigned Opcode = 0;
3459 if (Src.hasOneUse()) {
3460 switch (Src.getOpcode()) {
3461 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3462 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3463 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3464 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3465 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3466 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3472 C.Op0 = Src->getOperand(0);
3473 C.Op1 = Src->getOperand(1);
3477 C.CCMask ^=
C.CCValid;
3489 C.Opcode = SystemZISD::VICMPES;
3501 bool Swap =
false, Invert =
false;
3513 C.Opcode = SystemZISD::UCMP128HI;
3515 C.Opcode = SystemZISD::SCMP128HI;
3520 C.CCMask ^=
C.CCValid;
3531 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3534 if ((~
Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3537 C.Op0 =
C.Op0.getOperand(0);
3549 C.CCValid = CCValid;
3552 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3555 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3559 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3562 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3566 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3569 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3572 C.CCMask &= CCValid;
3580 bool IsSignaling =
false) {
3583 unsigned Opcode, CCValid;
3595 Comparison
C(CmpOp0, CmpOp1, Chain);
3597 if (
C.Op0.getValueType().isFloatingPoint()) {
3600 C.Opcode = SystemZISD::FCMP;
3601 else if (!IsSignaling)
3602 C.Opcode = SystemZISD::STRICT_FCMP;
3604 C.Opcode = SystemZISD::STRICT_FCMPS;
3609 C.Opcode = SystemZISD::ICMP;
3645 if (!
C.Op1.getNode()) {
3646 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3647 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3649 switch (
C.Op0.getOpcode()) {
3660 if (
C.Opcode == SystemZISD::ICMP)
3661 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3663 if (
C.Opcode == SystemZISD::TM) {
3666 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3669 if (
C.Opcode == SystemZISD::VICMPES ||
3670 C.Opcode == SystemZISD::VICMPHS ||
3671 C.Opcode == SystemZISD::VICMPHLS ||
3672 C.Opcode == SystemZISD::VFCMPES ||
3673 C.Opcode == SystemZISD::VFCMPHS ||
3674 C.Opcode == SystemZISD::VFCMPHES) {
3675 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3682 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3684 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3693 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3694 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3719 unsigned CCValid,
unsigned CCMask) {
3724 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3802 int Mask[] = { Start, -1, Start + 1, -1 };
3806 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3808 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3822 !Subtarget.hasVectorEnhancements1()) {
3828 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3841 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3844 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3845 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3847 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3860 bool IsSignaling)
const {
3863 assert (!IsSignaling || Chain);
3866 bool Invert =
false;
3874 assert(IsFP &&
"Unexpected integer comparison");
3876 DL, VT, CmpOp1, CmpOp0, Chain);
3878 DL, VT, CmpOp0, CmpOp1, Chain);
3882 LT.getValue(1),
GE.getValue(1));
3891 assert(IsFP &&
"Unexpected integer comparison");
3893 DL, VT, CmpOp1, CmpOp0, Chain);
3895 DL, VT, CmpOp0, CmpOp1, Chain);
3899 LT.getValue(1),
GT.getValue(1));
3920 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3924 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3929 Chain =
Cmp.getValue(1);
3937 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3950 EVT VT =
Op.getValueType();
3952 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3961 bool IsSignaling)
const {
3967 EVT VT =
Op.getNode()->getValueType(0);
3969 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3970 Chain, IsSignaling);
3992 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4026 C.CCMask ^=
C.CCValid;
4034 Op = SystemZISD::VICMPE;
4038 Op = SystemZISD::VICMPHL;
4040 Op = SystemZISD::VICMPH;
4079 C.Op1->getAsZExtVal() == 0) {
4086 if (Subtarget.hasVectorEnhancements3() &&
4087 C.Opcode == SystemZISD::ICMP &&
4088 C.Op0.getValueType() == MVT::i128 &&
4098 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4104 const GlobalValue *GV =
Node->getGlobal();
4110 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4113 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4132 }
else if (Subtarget.isTargetELF()) {
4137 }
else if (Subtarget.isTargetzOS()) {
4168 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4173 Ops.push_back(Chain);
4175 Node->getValueType(0),
4184 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4185 const uint32_t *
Mask =
4187 assert(Mask &&
"Missing call preserved mask for calling convention");
4191 Ops.push_back(Glue);
4194 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4202SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4226 const GlobalValue *GV =
Node->getGlobal();
4234 SDValue TP = lowerThreadPointer(
DL, DAG);
4241 SystemZConstantPoolValue *CPV =
4250 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4256 SystemZConstantPoolValue *CPV =
4265 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4270 SystemZMachineFunctionInfo* MFI =
4299 SystemZConstantPoolValue *CPV =
4333 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4350 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4355 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4357 MachineFrameInfo &MFI = MF.getFrameInfo();
4361 unsigned Depth =
Op.getConstantOperandVal(0);
4368 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4373 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4379 MachinePointerInfo());
4394 unsigned Depth =
Op.getConstantOperandVal(0);
4399 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4402 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4403 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4404 int Offset = TFL->getReturnAddressOffset(MF);
4408 MachinePointerInfo());
4413 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4415 &SystemZ::GR64BitRegClass);
4423 EVT InVT =
In.getValueType();
4424 EVT ResVT =
Op.getValueType();
4432 LoadN->getBasePtr(), LoadN->getMemOperand());
4438 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4440 if (Subtarget.hasHighWord()) {
4444 MVT::i64,
SDValue(U64, 0), In);
4452 DL, MVT::f32, Out64);
4454 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4457 MVT::f64,
SDValue(U64, 0), In);
4459 if (Subtarget.hasHighWord())
4472 if (Subtarget.isTargetXPLINK64())
4473 return lowerVASTART_XPLINK(
Op, DAG);
4475 return lowerVASTART_ELF(
Op, DAG);
4481 SystemZMachineFunctionInfo *FuncInfo =
4482 MF.
getInfo<SystemZMachineFunctionInfo>();
4492 MachinePointerInfo(SV));
4498 SystemZMachineFunctionInfo *FuncInfo =
4499 MF.
getInfo<SystemZMachineFunctionInfo>();
4508 const unsigned NumFields = 4;
4519 for (
unsigned I = 0;
I < NumFields; ++
I) {
4524 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4525 MachinePointerInfo(SV,
Offset));
4545 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4546 MachinePointerInfo(SrcSV));
4550SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4552 if (Subtarget.isTargetXPLINK64())
4553 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4555 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4559SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4561 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4571 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4574 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4575 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4581 if (ExtraAlignSpace)
4585 bool IsSigned =
false;
4586 bool DoesNotReturn =
false;
4587 bool IsReturnValueUsed =
false;
4588 EVT VT =
Op.getValueType();
4598 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4610 if (ExtraAlignSpace) {
4622SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4624 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4627 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4636 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4639 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4640 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4651 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4652 MachinePointerInfo());
4655 if (ExtraAlignSpace)
4662 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4663 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4679 if (RequiredAlign > StackAlign) {
4689 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4690 MachinePointerInfo());
4696SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4700 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4705 unsigned Opcode)
const {
4706 EVT VT =
Op.getValueType();
4712 assert(Subtarget.hasMiscellaneousExtensions2());
4717 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4723 EVT VT =
Op.getValueType();
4731 else if (Subtarget.hasMiscellaneousExtensions2())
4736 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4771 EVT VT =
Op.getValueType();
4784 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4792 EVT VT =
Op.getValueType();
4812 EVT VT =
Op.getValueType();
4819 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4824 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4833 uint64_t Masks[] = {
Known[0].Zero.getZExtValue(),
4834 Known[1].Zero.getZExtValue() };
4836 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4838 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4875 MVT::i64, HighOp, Low32);
4881 SDNode *
N =
Op.getNode();
4886 if (
N->getValueType(0) == MVT::i128) {
4887 unsigned BaseOp = 0;
4888 unsigned FlagOp = 0;
4889 bool IsBorrow =
false;
4890 switch (
Op.getOpcode()) {
4894 FlagOp = SystemZISD::VACC;
4898 FlagOp = SystemZISD::VSCBI;
4913 unsigned BaseOp = 0;
4914 unsigned CCValid = 0;
4915 unsigned CCMask = 0;
4917 switch (
Op.getOpcode()) {
4920 BaseOp = SystemZISD::SADDO;
4925 BaseOp = SystemZISD::SSUBO;
4930 BaseOp = SystemZISD::UADDO;
4935 BaseOp = SystemZISD::USUBO;
4941 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4945 if (
N->getValueType(1) == MVT::i1)
4971 SDNode *
N =
Op.getNode();
4972 MVT VT =
N->getSimpleValueType(0);
4983 if (VT == MVT::i128) {
4984 unsigned BaseOp = 0;
4985 unsigned FlagOp = 0;
4986 bool IsBorrow =
false;
4987 switch (
Op.getOpcode()) {
4990 BaseOp = SystemZISD::VAC;
4991 FlagOp = SystemZISD::VACCC;
4994 BaseOp = SystemZISD::VSBI;
4995 FlagOp = SystemZISD::VSBCBI;
5014 unsigned BaseOp = 0;
5015 unsigned CCValid = 0;
5016 unsigned CCMask = 0;
5018 switch (
Op.getOpcode()) {
5024 BaseOp = SystemZISD::ADDCARRY;
5032 BaseOp = SystemZISD::SUBCARRY;
5043 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5047 if (
N->getValueType(1) == MVT::i1)
5055 EVT VT =
Op.getValueType();
5057 Op =
Op.getOperand(0);
5080 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5092 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5105 if (NumSignificantBits == 0)
5111 BitSize = std::min(BitSize, OrigBitSize);
5120 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5122 if (BitSize != OrigBitSize)
5159 EVT RegVT =
Op.getValueType();
5161 return lowerATOMIC_LDST_I128(
Op, DAG);
5162 return lowerLoadF16(
Op, DAG);
5168 if (
Node->getMemoryVT().getSizeInBits() == 128)
5169 return lowerATOMIC_LDST_I128(
Op, DAG);
5170 return lowerStoreF16(
Op, DAG);
5177 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5178 "Only custom lowering i128 or f128.");
5191 EVT WideVT = MVT::i32;
5214 unsigned Opcode)
const {
5218 EVT NarrowVT =
Node->getMemoryVT();
5219 EVT WideVT = MVT::i32;
5220 if (NarrowVT == WideVT)
5227 MachineMemOperand *MMO =
Node->getMemOperand();
5231 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5233 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5238 SDValue AlignedAddr, BitShift, NegBitShift;
5246 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5249 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5250 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5255 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5256 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5276 EVT MemVT =
Node->getMemoryVT();
5277 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5279 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5280 assert(Subtarget.hasInterlockedAccess1() &&
5281 "Should have been expanded by AtomicExpand pass.");
5287 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5288 Node->getMemOperand());
5291 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5302 MachineMemOperand *MMO =
Node->getMemOperand();
5305 if (
Node->getMemoryVT() == MVT::i128) {
5314 EVT NarrowVT =
Node->getMemoryVT();
5315 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5316 if (NarrowVT == WideVT) {
5317 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5318 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5320 DL, Tys,
Ops, NarrowVT, MMO);
5334 SDValue AlignedAddr, BitShift, NegBitShift;
5338 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5339 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5342 VTList,
Ops, NarrowVT, MMO);
5356SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5379 auto *Regs = Subtarget.getSpecialRegisters();
5382 "in GHC calling convention");
5384 Regs->getStackPointerRegister(),
Op.getValueType());
5390 auto *Regs = Subtarget.getSpecialRegisters();
5391 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5395 "in GHC calling convention");
5402 if (StoreBackchain) {
5404 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5405 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5406 MachinePointerInfo());
5409 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5412 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5413 MachinePointerInfo());
5420 bool IsData =
Op.getConstantOperandVal(4);
5423 return Op.getOperand(0);
5426 bool IsWrite =
Op.getConstantOperandVal(2);
5433 Node->getMemoryVT(),
Node->getMemOperand());
5437SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5439 unsigned Opcode, CCValid;
5441 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5452SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5454 unsigned Opcode, CCValid;
5457 if (
Op->getNumValues() == 1)
5459 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5464 unsigned Id =
Op.getConstantOperandVal(0);
5466 case Intrinsic::thread_pointer:
5467 return lowerThreadPointer(SDLoc(
Op), DAG);
5469 case Intrinsic::s390_vpdi:
5470 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5471 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5473 case Intrinsic::s390_vperm:
5474 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5475 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5477 case Intrinsic::s390_vuphb:
5478 case Intrinsic::s390_vuphh:
5479 case Intrinsic::s390_vuphf:
5480 case Intrinsic::s390_vuphg:
5481 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5484 case Intrinsic::s390_vuplhb:
5485 case Intrinsic::s390_vuplhh:
5486 case Intrinsic::s390_vuplhf:
5487 case Intrinsic::s390_vuplhg:
5488 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5491 case Intrinsic::s390_vuplb:
5492 case Intrinsic::s390_vuplhw:
5493 case Intrinsic::s390_vuplf:
5494 case Intrinsic::s390_vuplg:
5495 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5498 case Intrinsic::s390_vupllb:
5499 case Intrinsic::s390_vupllh:
5500 case Intrinsic::s390_vupllf:
5501 case Intrinsic::s390_vupllg:
5502 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5505 case Intrinsic::s390_vsumb:
5506 case Intrinsic::s390_vsumh:
5507 case Intrinsic::s390_vsumgh:
5508 case Intrinsic::s390_vsumgf:
5509 case Intrinsic::s390_vsumqf:
5510 case Intrinsic::s390_vsumqg:
5511 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5512 Op.getOperand(1),
Op.getOperand(2));
5514 case Intrinsic::s390_vaq:
5516 Op.getOperand(1),
Op.getOperand(2));
5517 case Intrinsic::s390_vaccb:
5518 case Intrinsic::s390_vacch:
5519 case Intrinsic::s390_vaccf:
5520 case Intrinsic::s390_vaccg:
5521 case Intrinsic::s390_vaccq:
5522 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5523 Op.getOperand(1),
Op.getOperand(2));
5524 case Intrinsic::s390_vacq:
5525 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5526 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5527 case Intrinsic::s390_vacccq:
5528 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5529 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5531 case Intrinsic::s390_vsq:
5533 Op.getOperand(1),
Op.getOperand(2));
5534 case Intrinsic::s390_vscbib:
5535 case Intrinsic::s390_vscbih:
5536 case Intrinsic::s390_vscbif:
5537 case Intrinsic::s390_vscbig:
5538 case Intrinsic::s390_vscbiq:
5539 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5540 Op.getOperand(1),
Op.getOperand(2));
5541 case Intrinsic::s390_vsbiq:
5542 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5543 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5544 case Intrinsic::s390_vsbcbiq:
5545 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5546 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5548 case Intrinsic::s390_vmhb:
5549 case Intrinsic::s390_vmhh:
5550 case Intrinsic::s390_vmhf:
5551 case Intrinsic::s390_vmhg:
5552 case Intrinsic::s390_vmhq:
5554 Op.getOperand(1),
Op.getOperand(2));
5555 case Intrinsic::s390_vmlhb:
5556 case Intrinsic::s390_vmlhh:
5557 case Intrinsic::s390_vmlhf:
5558 case Intrinsic::s390_vmlhg:
5559 case Intrinsic::s390_vmlhq:
5561 Op.getOperand(1),
Op.getOperand(2));
5563 case Intrinsic::s390_vmahb:
5564 case Intrinsic::s390_vmahh:
5565 case Intrinsic::s390_vmahf:
5566 case Intrinsic::s390_vmahg:
5567 case Intrinsic::s390_vmahq:
5568 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5569 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5570 case Intrinsic::s390_vmalhb:
5571 case Intrinsic::s390_vmalhh:
5572 case Intrinsic::s390_vmalhf:
5573 case Intrinsic::s390_vmalhg:
5574 case Intrinsic::s390_vmalhq:
5575 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5576 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5578 case Intrinsic::s390_vmeb:
5579 case Intrinsic::s390_vmeh:
5580 case Intrinsic::s390_vmef:
5581 case Intrinsic::s390_vmeg:
5582 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5583 Op.getOperand(1),
Op.getOperand(2));
5584 case Intrinsic::s390_vmleb:
5585 case Intrinsic::s390_vmleh:
5586 case Intrinsic::s390_vmlef:
5587 case Intrinsic::s390_vmleg:
5588 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5589 Op.getOperand(1),
Op.getOperand(2));
5590 case Intrinsic::s390_vmob:
5591 case Intrinsic::s390_vmoh:
5592 case Intrinsic::s390_vmof:
5593 case Intrinsic::s390_vmog:
5594 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5595 Op.getOperand(1),
Op.getOperand(2));
5596 case Intrinsic::s390_vmlob:
5597 case Intrinsic::s390_vmloh:
5598 case Intrinsic::s390_vmlof:
5599 case Intrinsic::s390_vmlog:
5600 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5601 Op.getOperand(1),
Op.getOperand(2));
5603 case Intrinsic::s390_vmaeb:
5604 case Intrinsic::s390_vmaeh:
5605 case Intrinsic::s390_vmaef:
5606 case Intrinsic::s390_vmaeg:
5608 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5609 Op.getOperand(1),
Op.getOperand(2)),
5611 case Intrinsic::s390_vmaleb:
5612 case Intrinsic::s390_vmaleh:
5613 case Intrinsic::s390_vmalef:
5614 case Intrinsic::s390_vmaleg:
5616 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5617 Op.getOperand(1),
Op.getOperand(2)),
5619 case Intrinsic::s390_vmaob:
5620 case Intrinsic::s390_vmaoh:
5621 case Intrinsic::s390_vmaof:
5622 case Intrinsic::s390_vmaog:
5624 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5625 Op.getOperand(1),
Op.getOperand(2)),
5627 case Intrinsic::s390_vmalob:
5628 case Intrinsic::s390_vmaloh:
5629 case Intrinsic::s390_vmalof:
5630 case Intrinsic::s390_vmalog:
5632 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5633 Op.getOperand(1),
Op.getOperand(2)),
5654 { SystemZISD::MERGE_HIGH, 8,
5655 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5657 { SystemZISD::MERGE_HIGH, 4,
5658 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5660 { SystemZISD::MERGE_HIGH, 2,
5661 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5663 { SystemZISD::MERGE_HIGH, 1,
5664 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5666 { SystemZISD::MERGE_LOW, 8,
5667 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5669 { SystemZISD::MERGE_LOW, 4,
5670 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5672 { SystemZISD::MERGE_LOW, 2,
5673 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5675 { SystemZISD::MERGE_LOW, 1,
5676 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5678 { SystemZISD::PACK, 4,
5679 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5681 { SystemZISD::PACK, 2,
5682 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5684 { SystemZISD::PACK, 1,
5685 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5687 { SystemZISD::PERMUTE_DWORDS, 4,
5688 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5690 { SystemZISD::PERMUTE_DWORDS, 1,
5691 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5705 OpNo0 = OpNo1 = OpNos[1];
5706 }
else if (OpNos[1] < 0) {
5707 OpNo0 = OpNo1 = OpNos[0];
5725 unsigned &OpNo0,
unsigned &OpNo1) {
5726 int OpNos[] = { -1, -1 };
5739 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5741 OpNos[ModelOpNo] = RealOpNo;
5749 unsigned &OpNo0,
unsigned &OpNo1) {
5766 int Elt = Bytes[From];
5769 Transform[From] = -1;
5771 while (
P.Bytes[To] != Elt) {
5776 Transform[From] = To;
5800 Bytes.
resize(NumElements * BytesPerElement, -1);
5801 for (
unsigned I = 0;
I < NumElements; ++
I) {
5802 int Index = VSN->getMaskElt(
I);
5804 for (
unsigned J = 0; J < BytesPerElement; ++J)
5805 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5809 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5812 Bytes.
resize(NumElements * BytesPerElement, -1);
5813 for (
unsigned I = 0;
I < NumElements; ++
I)
5814 for (
unsigned J = 0; J < BytesPerElement; ++J)
5815 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5826 unsigned BytesPerElement,
int &
Base) {
5828 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5829 if (Bytes[Start +
I] >= 0) {
5830 unsigned Elem = Bytes[Start +
I];
5834 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5836 }
else if (
unsigned(
Base) != Elem -
I)
5849 unsigned &StartIndex,
unsigned &OpNo0,
5851 int OpNos[] = { -1, -1 };
5853 for (
unsigned I = 0;
I < 16; ++
I) {
5854 int Index = Bytes[
I];
5860 Shift = ExpectedShift;
5861 else if (Shift != ExpectedShift)
5865 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5867 OpNos[ModelOpNo] = RealOpNo;
5880 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5881 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5889 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5891 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5892 }
else if (
P.Opcode == SystemZISD::PACK) {
5895 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5904 N =
N->getOperand(0);
5907 return Op->getZExtValue() == 0;
5913 for (
unsigned I = 0;
I < Num ;
I++)
5925 for (
unsigned I = 0;
I < 2; ++
I)
5929 unsigned StartIndex, OpNo0, OpNo1;
5931 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5938 if (ZeroVecIdx != UINT32_MAX) {
5939 bool MaskFirst =
true;
5944 if (OpNo == ZeroVecIdx &&
I == 0) {
5949 if (OpNo != ZeroVecIdx && Byte == 0) {
5956 if (ZeroIdx != -1) {
5959 if (Bytes[
I] >= 0) {
5962 if (OpNo == ZeroVecIdx)
5974 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5977 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5989 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5995struct GeneralShuffle {
5996 GeneralShuffle(EVT vt)
5997 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
6001 void tryPrepareForUnpack();
6002 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6017 unsigned UnpackFromEltSize;
6024void GeneralShuffle::addUndef() {
6026 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6027 Bytes.push_back(-1);
6036bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6042 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6047 if (FromBytesPerElement < BytesPerElement)
6051 (FromBytesPerElement - BytesPerElement));
6054 while (
Op.getNode()) {
6056 Op =
Op.getOperand(0);
6072 }
else if (
Op.isUndef()) {
6081 for (; OpNo <
Ops.size(); ++OpNo)
6082 if (
Ops[OpNo] ==
Op)
6084 if (OpNo ==
Ops.size())
6089 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6090 Bytes.push_back(
Base +
I);
6099 if (
Ops.size() == 0)
6103 tryPrepareForUnpack();
6106 if (
Ops.size() == 1)
6118 unsigned Stride = 1;
6119 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6120 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6130 else if (OpNo ==
I + Stride)
6141 if (NewBytes[J] >= 0) {
6143 "Invalid double permute");
6146 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6152 if (NewBytes[J] >= 0)
6168 unsigned OpNo0, OpNo1;
6172 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6177 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6184 dbgs() <<
Msg.c_str() <<
" { ";
6185 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6186 dbgs() << Bytes[
I] <<
" ";
6194void GeneralShuffle::tryPrepareForUnpack() {
6196 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6201 if (
Ops.size() > 2 &&
6206 UnpackFromEltSize = 1;
6207 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6208 bool MatchUnpack =
true;
6211 unsigned ToEltSize = UnpackFromEltSize * 2;
6212 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6215 if (Bytes[Elt] != -1) {
6217 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6218 MatchUnpack =
false;
6224 if (
Ops.size() == 2) {
6226 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6228 if (SrcBytes[i] == -1)
6230 if (SrcBytes[i] % 16 !=
int(i))
6231 CanUseUnpackHigh =
false;
6233 CanUseUnpackLow =
false;
6234 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6235 UnpackFromEltSize = UINT_MAX;
6239 if (!CanUseUnpackHigh)
6245 if (UnpackFromEltSize > 4)
6248 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6249 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6251 dumpBytes(Bytes,
"Original Bytes vector:"););
6260 Elt += UnpackFromEltSize;
6261 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6262 Bytes[
B] = Bytes[Elt];
6270 Ops.erase(&
Ops[ZeroVecOpNo]);
6272 if (Bytes[
I] >= 0) {
6274 if (OpNo > ZeroVecOpNo)
6285 if (!unpackWasPrepared())
6287 unsigned InBits = UnpackFromEltSize * 8;
6291 unsigned OutBits = InBits * 2;
6294 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6295 : SystemZISD::UNPACKL_HIGH,
6296 DL, OutVT, PackedOp);
6301 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6302 if (!
Op.getOperand(
I).isUndef())
6318 if (
Value.isUndef())
6330 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6333 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6334 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6355 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6371 GeneralShuffle GS(VT);
6373 bool FoundOne =
false;
6374 for (
unsigned I = 0;
I < NumElements; ++
I) {
6377 Op =
Op.getOperand(0);
6380 unsigned Elem =
Op.getConstantOperandVal(1);
6381 if (!GS.add(
Op.getOperand(0), Elem))
6384 }
else if (
Op.isUndef()) {
6398 if (!ResidueOps.
empty()) {
6399 while (ResidueOps.
size() < NumElements)
6401 for (
auto &
Op : GS.Ops) {
6402 if (!
Op.getNode()) {
6408 return GS.getNode(DAG,
SDLoc(BVN));
6411bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6417 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6428 "Handling full vectors only.");
6448 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6460 unsigned int NumElements = Elems.
size();
6461 unsigned int Count = 0;
6462 for (
auto Elem : Elems) {
6463 if (!Elem.isUndef()) {
6466 else if (Elem != Single) {
6486 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6487 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6490 bool AllLoads =
true;
6491 for (
auto Elem : Elems)
6492 if (!isVectorElementLoad(Elem)) {
6498 if (VT == MVT::v2i64 && !AllLoads)
6502 if (VT == MVT::v2f64 && !AllLoads)
6512 if (VT == MVT::v4f32 && !AllLoads)
6516 if (VT == MVT::v8f16 && !AllLoads) {
6525 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6534 unsigned NumConstants = 0;
6535 for (
unsigned I = 0;
I < NumElements; ++
I) {
6549 if (NumConstants > 0) {
6550 for (
unsigned I = 0;
I < NumElements; ++
I)
6561 std::map<const SDNode*, unsigned> UseCounts;
6562 SDNode *LoadMaxUses =
nullptr;
6563 for (
unsigned I = 0;
I < NumElements; ++
I)
6564 if (isVectorElementLoad(Elems[
I])) {
6565 SDNode *Ld = Elems[
I].getNode();
6566 unsigned Count = ++UseCounts[Ld];
6567 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6570 if (LoadMaxUses !=
nullptr) {
6571 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6575 unsigned I1 = NumElements / 2 - 1;
6576 unsigned I2 = NumElements - 1;
6577 bool Def1 = !Elems[
I1].isUndef();
6578 bool Def2 = !Elems[I2].isUndef();
6592 for (
unsigned I = 0;
I < NumElements; ++
I)
6593 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6603 EVT VT =
Op.getValueType();
6605 if (BVN->isConstant()) {
6606 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6624 for (
unsigned I = 0;
I < NumElements; ++
I)
6626 return buildVector(DAG,
DL, VT,
Ops);
6633 EVT VT =
Op.getValueType();
6636 if (VSN->isSplat()) {
6638 unsigned Index = VSN->getSplatIndex();
6640 "Splat index should be defined and in first operand");
6646 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6650 GeneralShuffle
GS(VT);
6651 for (
unsigned I = 0;
I < NumElements; ++
I) {
6652 int Elt = VSN->getMaskElt(
I);
6655 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6656 unsigned(Elt) % NumElements))
6659 return GS.getNode(DAG, SDLoc(VSN));
6674 assert(
Op.getSimpleValueType() == MVT::i64 &&
6675 "Expexted to convert i64 to f16.");
6687 assert(
Op.getSimpleValueType() == MVT::f16 &&
6688 "Expected to convert f16 to i64.");
6705 EVT VT =
Op.getValueType();
6710 if (VT == MVT::v2f64 &&
6734SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6740 EVT VT =
Op.getValueType();
6745 uint64_t
Index = CIndexN->getZExtValue();
6754 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6762SDValue SystemZTargetLowering::
6765 EVT OutVT =
Op.getValueType();
6769 unsigned StartOffset = 0;
6776 ArrayRef<int> ShuffleMask = SVN->
getMask();
6781 if (ToBits == 64 && OutNumElts == 2) {
6782 int NumElem = ToBits / FromBits;
6783 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6789 int StartOffsetCandidate = -1;
6790 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6791 if (ShuffleMask[Elt] == -1)
6793 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6794 if (StartOffsetCandidate == -1)
6795 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6796 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6799 StartOffsetCandidate = -1;
6802 if (StartOffsetCandidate != -1) {
6803 StartOffset = StartOffsetCandidate;
6812 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6813 if (StartOffset >= OutNumElts) {
6814 Opcode = SystemZISD::UNPACK_LOW;
6815 StartOffset -= OutNumElts;
6817 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6818 }
while (FromBits != ToBits);
6823SDValue SystemZTargetLowering::
6827 EVT OutVT =
Op.getValueType();
6831 unsigned NumInPerOut = InNumElts / OutNumElts;
6836 SmallVector<int, 16>
Mask(InNumElts);
6837 unsigned ZeroVecElt = InNumElts;
6838 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6839 unsigned MaskElt = PackedElt * NumInPerOut;
6840 unsigned End = MaskElt + NumInPerOut - 1;
6841 for (; MaskElt < End; MaskElt++)
6842 Mask[MaskElt] = ZeroVecElt++;
6843 Mask[MaskElt] = PackedElt;
6850 unsigned ByScalar)
const {
6855 EVT VT =
Op.getValueType();
6860 APInt SplatBits, SplatUndef;
6861 unsigned SplatBitSize;
6865 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6866 ElemBitSize,
true) &&
6867 SplatBitSize == ElemBitSize) {
6870 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6873 BitVector UndefElements;
6879 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6886 if (VSN->isSplat()) {
6887 SDValue VSNOp0 = VSN->getOperand(0);
6888 unsigned Index = VSN->getSplatIndex();
6890 "Splat index should be defined and in first operand");
6897 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6915 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6916 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6919 if (ShiftAmt > 120) {
6923 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6927 SmallVector<int, 16>
Mask(16);
6928 for (
unsigned Elt = 0; Elt < 16; Elt++)
6929 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6931 if ((ShiftAmt & 7) == 0)
6935 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6953 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6954 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6957 if (ShiftAmt > 120) {
6961 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6965 SmallVector<int, 16>
Mask(16);
6966 for (
unsigned Elt = 0; Elt < 16; Elt++)
6967 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6969 if ((ShiftAmt & 7) == 0)
6973 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6985 MVT DstVT =
Op.getSimpleValueType();
6988 unsigned SrcAS =
N->getSrcAddressSpace();
6990 assert(SrcAS !=
N->getDestAddressSpace() &&
6991 "addrspacecast must be between different address spaces");
6999 }
else if (DstVT == MVT::i32) {
7013 if (
In.getSimpleValueType() != MVT::f16)
7020 SDValue Chain,
bool IsStrict)
const {
7021 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7024 std::tie(Result, Chain) =
7033 bool IsStrict =
Op->isStrictFPOpcode();
7035 MVT VT =
Op.getSimpleValueType();
7036 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7044 if (!Subtarget.hasFPExtension() && !IsSigned)
7055 if (VT == MVT::i128) {
7058 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7068 bool IsStrict =
Op->isStrictFPOpcode();
7070 MVT VT =
Op.getSimpleValueType();
7071 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7076 if (VT == MVT::f16) {
7083 if (!Subtarget.hasFPExtension() && !IsSigned)
7086 if (InVT == MVT::i128) {
7089 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7098 EVT RegVT =
Op.getValueType();
7099 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7106 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7108 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7109 AtomicLd->getMemOperand());
7129 Shft, AtomicSt->getBasePtr(),
7130 AtomicSt->getMemOperand());
7140 MVT ResultVT =
Op.getSimpleValueType();
7142 unsigned Check =
Op.getConstantOperandVal(1);
7144 unsigned TDCMask = 0;
7179 MachinePointerInfo MPI =
7185 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7189 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7194 switch (
Op.getOpcode()) {
7196 return lowerFRAMEADDR(
Op, DAG);
7198 return lowerRETURNADDR(
Op, DAG);
7200 return lowerBR_CC(
Op, DAG);
7202 return lowerSELECT_CC(
Op, DAG);
7204 return lowerSETCC(
Op, DAG);
7206 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7208 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7220 return lowerBITCAST(
Op, DAG);
7222 return lowerVASTART(
Op, DAG);
7224 return lowerVACOPY(
Op, DAG);
7226 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7228 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7230 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7232 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7234 return lowerSMUL_LOHI(
Op, DAG);
7236 return lowerUMUL_LOHI(
Op, DAG);
7238 return lowerSDIVREM(
Op, DAG);
7240 return lowerUDIVREM(
Op, DAG);
7245 return lowerXALUO(
Op, DAG);
7248 return lowerUADDSUBO_CARRY(
Op, DAG);
7250 return lowerOR(
Op, DAG);
7252 return lowerCTPOP(
Op, DAG);
7254 return lowerVECREDUCE_ADD(
Op, DAG);
7256 return lowerATOMIC_FENCE(
Op, DAG);
7258 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7260 return lowerATOMIC_STORE(
Op, DAG);
7262 return lowerATOMIC_LOAD(
Op, DAG);
7264 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7266 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7268 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7270 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7272 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7274 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7276 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7278 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7280 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7282 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7284 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7286 return lowerSTACKSAVE(
Op, DAG);
7288 return lowerSTACKRESTORE(
Op, DAG);
7290 return lowerPREFETCH(
Op, DAG);
7292 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7294 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7296 return lowerBUILD_VECTOR(
Op, DAG);
7298 return lowerVECTOR_SHUFFLE(
Op, DAG);
7300 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7302 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7304 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7306 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7308 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7310 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7312 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7314 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7318 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7320 return lowerFSHL(
Op, DAG);
7322 return lowerFSHR(
Op, DAG);
7325 return lowerFP_EXTEND(
Op, DAG);
7330 return lower_FP_TO_INT(
Op, DAG);
7335 return lower_INT_TO_FP(
Op, DAG);
7337 return lowerLoadF16(
Op, DAG);
7339 return lowerStoreF16(
Op, DAG);
7341 return lowerIS_FPCLASS(
Op, DAG);
7343 return lowerGET_ROUNDING(
Op, DAG);
7345 return lowerREADCYCLECOUNTER(
Op, DAG);
7367 &SystemZ::FP128BitRegClass);
7376 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7391 &SystemZ::FP128BitRegClass);
7408 switch (
N->getOpcode()) {
7412 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7415 DL, Tys,
Ops, MVT::i128, MMO);
7418 if (
N->getValueType(0) == MVT::f128)
7432 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7435 DL, Tys,
Ops, MVT::i128, MMO);
7441 MVT::Other, Res), 0);
7453 DL, Tys,
Ops, MVT::i128, MMO);
7467 EVT SrcVT = Src.getValueType();
7468 EVT ResVT =
N->getValueType(0);
7469 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7471 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7472 if (Subtarget.hasVector()) {
7480 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7482 Subtarget.hasVector()
7496 bool IsStrict =
N->isStrictFPOpcode();
7498 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7499 EVT ResVT =
N->getValueType(0);
7501 if (ResVT == MVT::f16) {
7524 bool IsStrict =
N->isStrictFPOpcode();
7526 EVT ResVT =
N->getValueType(0);
7527 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7530 if (InVT == MVT::f16) {
7536 std::tie(InF32, Chain) =
7561bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7562 if (!Subtarget.hasVector())
7576 DAGCombinerInfo &DCI,
7584 unsigned Opcode =
Op.getOpcode();
7587 Op =
Op.getOperand(0);
7589 canTreatAsByteVector(
Op.getValueType())) {
7598 BytesPerElement,
First))
7605 if (Byte % BytesPerElement != 0)
7608 Index = Byte / BytesPerElement;
7612 canTreatAsByteVector(
Op.getValueType())) {
7615 EVT OpVT =
Op.getValueType();
7617 if (OpBytesPerElement < BytesPerElement)
7621 unsigned End = (
Index + 1) * BytesPerElement;
7622 if (End % OpBytesPerElement != 0)
7625 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7626 if (!
Op.getValueType().isInteger()) {
7629 DCI.AddToWorklist(
Op.getNode());
7634 DCI.AddToWorklist(
Op.getNode());
7641 canTreatAsByteVector(
Op.getValueType()) &&
7642 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7644 EVT ExtVT =
Op.getValueType();
7645 EVT OpVT =
Op.getOperand(0).getValueType();
7648 unsigned Byte =
Index * BytesPerElement;
7649 unsigned SubByte =
Byte % ExtBytesPerElement;
7650 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7651 if (SubByte < MinSubByte ||
7652 SubByte + BytesPerElement > ExtBytesPerElement)
7655 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7657 Byte += SubByte - MinSubByte;
7658 if (Byte % BytesPerElement != 0)
7660 Op =
Op.getOperand(0);
7667 if (
Op.getValueType() != VecVT) {
7669 DCI.AddToWorklist(
Op.getNode());
7679SDValue SystemZTargetLowering::combineTruncateExtract(
7688 if (canTreatAsByteVector(VecVT)) {
7692 if (BytesPerElement % TruncBytes == 0) {
7698 unsigned Scale = BytesPerElement / TruncBytes;
7699 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7706 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7707 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7715SDValue SystemZTargetLowering::combineZERO_EXTEND(
7716 SDNode *
N, DAGCombinerInfo &DCI)
const {
7718 SelectionDAG &DAG = DCI.DAG;
7720 EVT VT =
N->getValueType(0);
7721 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7724 if (TrueOp && FalseOp) {
7734 DCI.CombineTo(N0.
getNode(), TruncSelect);
7777 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7795SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7796 SDNode *
N, DAGCombinerInfo &DCI)
const {
7800 SelectionDAG &DAG = DCI.DAG;
7802 EVT VT =
N->getValueType(0);
7816SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7817 SDNode *
N, DAGCombinerInfo &DCI)
const {
7821 SelectionDAG &DAG = DCI.DAG;
7823 EVT VT =
N->getValueType(0);
7830 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7831 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7847SDValue SystemZTargetLowering::combineMERGE(
7848 SDNode *
N, DAGCombinerInfo &DCI)
const {
7849 SelectionDAG &DAG = DCI.DAG;
7850 unsigned Opcode =
N->getOpcode();
7858 if (Op1 ==
N->getOperand(0))
7863 if (ElemBytes <= 4) {
7864 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7865 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7871 DCI.AddToWorklist(Op1.
getNode());
7874 DCI.AddToWorklist(
Op.getNode());
7883 LoPart = HiPart =
nullptr;
7888 if (
Use.getResNo() != 0)
7893 bool IsLoPart =
true;
7918 LoPart = HiPart =
nullptr;
7923 if (
Use.getResNo() != 0)
7929 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7932 switch (
User->getConstantOperandVal(1)) {
7933 case SystemZ::subreg_l64:
7938 case SystemZ::subreg_h64:
7950SDValue SystemZTargetLowering::combineLOAD(
7951 SDNode *
N, DAGCombinerInfo &DCI)
const {
7952 SelectionDAG &DAG = DCI.DAG;
7953 EVT LdVT =
N->getValueType(0);
7957 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7958 if (PtrVT != LoadNodeVT) {
7962 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7963 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7964 LN->getMemOperand());
7974 SDNode *LoPart, *HiPart;
7982 LD->getPointerInfo(),
LD->getBaseAlign(),
7983 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7985 DCI.CombineTo(HiPart, EltLoad,
true);
7992 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7993 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7995 DCI.CombineTo(LoPart, EltLoad,
true);
8002 DCI.AddToWorklist(Chain.
getNode());
8017 for (SDUse &Use :
N->uses()) {
8018 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8022 }
else if (
Use.getResNo() == 0)
8025 if (!Replicate || OtherUses.
empty())
8031 for (SDNode *U : OtherUses) {
8034 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8040bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8041 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8043 if (Subtarget.hasVectorEnhancements2())
8044 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8056 for (
unsigned i = 0; i < NumElts; ++i) {
8057 if (M[i] < 0)
continue;
8058 if ((
unsigned) M[i] != NumElts - 1 - i)
8066 for (
auto *U : StoredVal->
users()) {
8068 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8127SDValue SystemZTargetLowering::combineSTORE(
8128 SDNode *
N, DAGCombinerInfo &DCI)
const {
8129 SelectionDAG &DAG = DCI.DAG;
8132 EVT MemVT = SN->getMemoryVT();
8136 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8137 if (PtrVT != StoreNodeVT) {
8141 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8142 SN->getPointerInfo(), SN->getBaseAlign(),
8143 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8151 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8153 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8154 DCI.AddToWorklist(
Value.getNode());
8158 SN->getBasePtr(), SN->getMemoryVT(),
8159 SN->getMemOperand());
8170 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8174 if (!SN->isTruncatingStore() &&
8190 Ops, MemVT, SN->getMemOperand());
8193 if (!SN->isTruncatingStore() &&
8196 Subtarget.hasVectorEnhancements2()) {
8198 ArrayRef<int> ShuffleMask = SVN->
getMask();
8206 Ops, MemVT, SN->getMemOperand());
8211 if (!SN->isTruncatingStore() &&
8214 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8218 Ops, MemVT, SN->getMemOperand());
8228 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8229 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8231 SN->getChain(),
DL, LoPart,
8233 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8234 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8252 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8254 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8258 APInt Val =
C->getAPIntValue();
8261 assert(SN->isTruncatingStore() &&
8262 "Non-truncating store and immediate value does not fit?");
8263 Val = Val.
trunc(TotBytes * 8);
8266 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8267 if (VCI.isVectorConstantLegal(Subtarget) &&
8268 VCI.Opcode == SystemZISD::REPLICATE) {
8276 auto FindReplicatedReg = [&](
SDValue MulOp) {
8277 EVT MulVT = MulOp.getValueType();
8278 if (MulOp->getOpcode() ==
ISD::MUL &&
8279 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8283 WordVT =
LHS->getOperand(0).getValueType();
8290 SystemZVectorConstantInfo VCI(
8292 if (VCI.isVectorConstantLegal(Subtarget) &&
8293 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8294 WordVT == VCI.VecVT.getScalarType())
8306 FindReplicatedReg(SplatVal);
8311 FindReplicatedReg(Op1);
8316 "Bad type handling");
8320 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8321 SN->getBasePtr(), SN->getMemOperand());
8328SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8329 SDNode *
N, DAGCombinerInfo &DCI)
const {
8330 SelectionDAG &DAG = DCI.DAG;
8333 N->getOperand(0).hasOneUse() &&
8334 Subtarget.hasVectorEnhancements2()) {
8336 ArrayRef<int> ShuffleMask = SVN->
getMask();
8349 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8353 DCI.CombineTo(
N, ESLoad);
8357 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8367SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8368 SDNode *
N, DAGCombinerInfo &DCI)
const {
8369 SelectionDAG &DAG = DCI.DAG;
8371 if (!Subtarget.hasVector())
8377 Op.getValueType().isVector() &&
8378 Op.getOperand(0).getValueType().isVector() &&
8379 Op.getValueType().getVectorNumElements() ==
8380 Op.getOperand(0).getValueType().getVectorNumElements())
8381 Op =
Op.getOperand(0);
8385 EVT VecVT =
Op.getValueType();
8388 Op.getOperand(0),
N->getOperand(1));
8389 DCI.AddToWorklist(
Op.getNode());
8391 if (EltVT !=
N->getValueType(0)) {
8392 DCI.AddToWorklist(
Op.getNode());
8402 if (canTreatAsByteVector(VecVT))
8403 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8404 IndexN->getZExtValue(), DCI,
false);
8409SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8410 SDNode *
N, DAGCombinerInfo &DCI)
const {
8411 SelectionDAG &DAG = DCI.DAG;
8413 if (
N->getOperand(0) ==
N->getOperand(1))
8414 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8424 if (Chain1 == Chain2)
8432SDValue SystemZTargetLowering::combineFP_ROUND(
8433 SDNode *
N, DAGCombinerInfo &DCI)
const {
8435 if (!Subtarget.hasVector())
8444 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8445 SelectionDAG &DAG = DCI.DAG;
8447 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8453 for (
auto *U : Vec->
users()) {
8454 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8456 U->getOperand(0) == Vec &&
8458 U->getConstantOperandVal(1) == 1) {
8460 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8464 if (
N->isStrictFPOpcode()) {
8468 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8469 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8472 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8474 DCI.AddToWorklist(VRound.
getNode());
8478 DCI.AddToWorklist(Extract1.
getNode());
8484 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8487 N->getVTList(), Extract0, Chain);
8496SDValue SystemZTargetLowering::combineFP_EXTEND(
8497 SDNode *
N, DAGCombinerInfo &DCI)
const {
8499 if (!Subtarget.hasVector())
8508 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8509 SelectionDAG &DAG = DCI.DAG;
8511 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8517 for (
auto *U : Vec->
users()) {
8518 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8520 U->getOperand(0) == Vec &&
8522 U->getConstantOperandVal(1) == 2) {
8524 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8528 if (
N->isStrictFPOpcode()) {
8532 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8533 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8536 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8538 DCI.AddToWorklist(VExtend.
getNode());
8542 DCI.AddToWorklist(Extract1.
getNode());
8548 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8551 N->getVTList(), Extract0, Chain);
8560SDValue SystemZTargetLowering::combineINT_TO_FP(
8561 SDNode *
N, DAGCombinerInfo &DCI)
const {
8564 SelectionDAG &DAG = DCI.DAG;
8566 unsigned Opcode =
N->getOpcode();
8567 EVT OutVT =
N->getValueType(0);
8571 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8577 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8578 OutScalarBits <= 64) {
8582 unsigned ExtOpcode =
8585 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8590SDValue SystemZTargetLowering::combineFCOPYSIGN(
8591 SDNode *
N, DAGCombinerInfo &DCI)
const {
8592 SelectionDAG &DAG = DCI.DAG;
8593 EVT VT =
N->getValueType(0);
8606SDValue SystemZTargetLowering::combineBSWAP(
8607 SDNode *
N, DAGCombinerInfo &DCI)
const {
8608 SelectionDAG &DAG = DCI.DAG;
8611 N->getOperand(0).hasOneUse() &&
8612 canLoadStoreByteSwapped(
N->getValueType(0))) {
8621 EVT LoadVT =
N->getValueType(0);
8622 if (LoadVT == MVT::i16)
8627 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8631 if (
N->getValueType(0) == MVT::i16)
8636 DCI.CombineTo(
N, ResVal);
8640 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8649 Op.getValueType().isVector() &&
8650 Op.getOperand(0).getValueType().isVector() &&
8651 Op.getValueType().getVectorNumElements() ==
8652 Op.getOperand(0).getValueType().getVectorNumElements())
8653 Op =
Op.getOperand(0);
8665 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8667 EVT VecVT =
N->getValueType(0);
8671 DCI.AddToWorklist(Vec.
getNode());
8675 DCI.AddToWorklist(Elt.
getNode());
8678 DCI.AddToWorklist(Vec.
getNode());
8680 DCI.AddToWorklist(Elt.
getNode());
8688 if (SV &&
Op.hasOneUse()) {
8696 EVT VecVT =
N->getValueType(0);
8699 DCI.AddToWorklist(Op0.
getNode());
8703 DCI.AddToWorklist(Op1.
getNode());
8706 DCI.AddToWorklist(Op0.
getNode());
8708 DCI.AddToWorklist(Op1.
getNode());
8716SDValue SystemZTargetLowering::combineSETCC(
8717 SDNode *
N, DAGCombinerInfo &DCI)
const {
8718 SelectionDAG &DAG = DCI.DAG;
8724 EVT VT =
N->getValueType(0);
8734 Src.getValueType().isFixedLengthVector() &&
8735 Src.getValueType().getScalarType() == MVT::i1) {
8736 EVT CmpVT = Src.getOperand(0).getValueType();
8753 unsigned Depth = 0) {
8761 case SystemZISD::IPM:
8766 case SystemZISD::SELECT_CCMASK: {
8768 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8769 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8772 return std::make_pair(OpCC, OpCCValid);
8777 int CCValidVal = CCValid->getZExtValue();
8778 return std::make_pair(Op4CCReg, CCValidVal);
8789 return std::make_pair(Op0CC, Op0CCValid);
8805 return {Val, Val, Val, Val};
8806 case SystemZISD::IPM: {
8811 for (
auto CC : {0, 1, 2, 3})
8814 return ShiftedCCVals;
8816 case SystemZISD::SELECT_CCMASK: {
8820 if (!CCValid || !CCMask)
8823 int CCValidVal = CCValid->getZExtValue();
8824 int CCMaskVal = CCMask->getZExtValue();
8834 if (TrueSDVals.empty() || FalseSDVals.empty())
8837 for (
auto &CCVal : {0, 1, 2, 3})
8838 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8840 : FalseSDVals[CCVal]);
8841 return MergedSDVals;
8858 if (Op0SDVals.empty() || Op1SDVals.empty())
8861 for (
auto CCVal : {0, 1, 2, 3})
8863 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8864 return BinaryOpSDVals;
8875 auto *CCNode = CCReg.
getNode();
8879 if (CCNode->getOpcode() == SystemZISD::TM) {
8882 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8885 if (!Op0Node || !Op1Node)
8887 auto Op0APVal = Op0Node->getAPIntValue();
8888 auto Op1APVal = Op1Node->getAPIntValue();
8889 auto Result = Op0APVal & Op1APVal;
8890 bool AllOnes = Result == Op1APVal;
8891 bool AllZeros = Result == 0;
8892 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8893 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8897 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8902 if (Op0SDVals.empty() || Op1SDVals.empty())
8905 for (
auto CC : {0, 1, 2, 3}) {
8906 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8910 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8912 NewCCMask &= Op0CCValid;
8915 CCValid = Op0CCValid;
8918 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8925 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8929 if (Op0SDVals.empty() || Op1SDVals.empty())
8933 auto CmpTypeVal = CmpType->getZExtValue();
8934 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8938 if (!Op0Node || !Op1Node)
8940 auto Op0APVal = Op0Node->getAPIntValue();
8941 auto Op1APVal = Op1Node->getAPIntValue();
8943 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8944 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8947 for (
auto CC : {0, 1, 2, 3}) {
8948 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8952 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8954 NewCCMask &= Op0CCValid;
8957 CCValid = Op0CCValid;
8970 const auto isFlagOutOpCC = [](
const Value *V) {
8972 const Value *RHSVal;
8979 if (CB->isInlineAsm()) {
8981 return IA && IA->getConstraintString().contains(
"{@cc}");
8992 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8995 return {-1, -1, -1};
8999 DAGCombinerInfo &DCI)
const {
9005 if (!CCValid || !CCMask)
9008 int CCValidVal = CCValid->getZExtValue();
9009 int CCMaskVal = CCMask->getZExtValue();
9016 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9017 CCMaskVal != CCValidVal)
9018 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9022 N->getOperand(3), CCReg);
9026SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9027 SDNode *
N, DAGCombinerInfo &DCI)
const {
9033 if (!CCValid || !CCMask)
9036 int CCValidVal = CCValid->getZExtValue();
9037 int CCMaskVal = CCMask->getZExtValue();
9040 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9044 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9045 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9047 if (Val.getOperand(4) != CCReg)
9054 int CCMaskVal = CCMask->getZExtValue();
9055 for (
auto &CC : {0, 1, 2, 3})
9056 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9070 if (TrueSDVals.empty())
9071 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9072 if (FalseSDVals.empty())
9073 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9074 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9075 SmallSet<SDValue, 4> MergedSDValsSet;
9077 for (
auto CC : {0, 1, 2, 3}) {
9078 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9079 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9083 if (MergedSDValsSet.
size() == 1)
9084 return *MergedSDValsSet.
begin();
9085 if (MergedSDValsSet.
size() == 2) {
9086 auto BeginIt = MergedSDValsSet.
begin();
9087 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9088 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9091 for (
auto CC : {0, 1, 2, 3}) {
9093 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9094 ? (TrueSDVals[CC] == NewTrueVal)
9095 : (FalseSDVals[CC] == NewTrueVal);
9097 CCMaskVal = NewCCMask;
9098 CCMaskVal &= CCValidVal;
9101 IsCombinedCCReg =
true;
9109 if (CCMaskVal == CCValidVal)
9112 if (IsCombinedCCReg)
9114 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9121SDValue SystemZTargetLowering::combineGET_CCMASK(
9122 SDNode *
N, DAGCombinerInfo &DCI)
const {
9127 if (!CCValid || !CCMask)
9129 int CCValidVal = CCValid->getZExtValue();
9130 int CCMaskVal = CCMask->getZExtValue();
9135 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9140 if (!SelectCCValid || !SelectCCMask)
9142 int SelectCCValidVal = SelectCCValid->getZExtValue();
9143 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9147 if (!TrueVal || !FalseVal)
9151 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9152 SelectCCMaskVal ^= SelectCCValidVal;
9156 if (SelectCCValidVal & ~CCValidVal)
9158 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9161 return Select->getOperand(4);
9164SDValue SystemZTargetLowering::combineIntDIVREM(
9165 SDNode *
N, DAGCombinerInfo &DCI)
const {
9166 SelectionDAG &DAG = DCI.DAG;
9167 EVT VT =
N->getValueType(0);
9184SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9185 SDNode *
N, DAGCombinerInfo &DCI)
const {
9186 SelectionDAG &DAG = DCI.DAG;
9190 "SRL or SRA node is required here!");
9192 if (!Subtarget.hasVector())
9202 SDValue ShiftOperand =
N->getOperand(0);
9222 if (!IsSignExt && !IsZeroExt)
9230 unsigned ActiveBits = IsSignExt
9231 ?
Constant->getAPIntValue().getSignificantBits()
9232 :
Constant->getAPIntValue().getActiveBits();
9233 if (ActiveBits > NarrowVTSize)
9249 unsigned ActiveBits = IsSignExt
9250 ?
Constant->getAPIntValue().getSignificantBits()
9251 :
Constant->getAPIntValue().getActiveBits();
9252 if (ActiveBits > NarrowVTSize)
9269 "Cannot have a multiply node with two different operand types.");
9271 "Cannot have an add node with two different operand types.");
9282 if (ShiftAmt != NarrowVTSize)
9286 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9287 NarrowVT == MVT::v4i32 ||
9288 (Subtarget.hasVectorEnhancements3() &&
9289 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9295 MulhRightOp, MulhAddOp);
9296 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9307 EVT VT =
Op.getValueType();
9316 Op =
Op.getOperand(0);
9317 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9321 bool CanUseEven =
true, CanUseOdd =
true;
9322 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9323 if (ShuffleMask[Elt] == -1)
9325 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9327 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9330 Op =
Op.getOperand(0);
9332 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9334 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9340 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9344 Op =
Op.getOperand(0);
9346 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9348 unsigned Elem =
Op.getConstantOperandVal(1);
9349 Op =
Op.getOperand(0);
9351 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9353 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9360SDValue SystemZTargetLowering::combineMUL(
9361 SDNode *
N, DAGCombinerInfo &DCI)
const {
9362 SelectionDAG &DAG = DCI.DAG;
9369 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9370 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9375SDValue SystemZTargetLowering::combineINTRINSIC(
9376 SDNode *
N, DAGCombinerInfo &DCI)
const {
9377 SelectionDAG &DAG = DCI.DAG;
9379 unsigned Id =
N->getConstantOperandVal(1);
9383 case Intrinsic::s390_vll:
9384 case Intrinsic::s390_vlrl:
9386 if (
C->getZExtValue() >= 15)
9387 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9388 N->getOperand(3), MachinePointerInfo());
9391 case Intrinsic::s390_vstl:
9392 case Intrinsic::s390_vstrl:
9394 if (
C->getZExtValue() >= 15)
9395 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9396 N->getOperand(4), MachinePointerInfo());
9404 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9411 switch(
N->getOpcode()) {
9416 case SystemZISD::MERGE_HIGH:
9417 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9422 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9432 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9433 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9436 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9437 case ISD::MUL:
return combineMUL(
N, DCI);
9441 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9453 EVT VT =
Op.getValueType();
9456 unsigned Opcode =
Op.getOpcode();
9458 unsigned Id =
Op.getConstantOperandVal(0);
9460 case Intrinsic::s390_vpksh:
9461 case Intrinsic::s390_vpksf:
9462 case Intrinsic::s390_vpksg:
9463 case Intrinsic::s390_vpkshs:
9464 case Intrinsic::s390_vpksfs:
9465 case Intrinsic::s390_vpksgs:
9466 case Intrinsic::s390_vpklsh:
9467 case Intrinsic::s390_vpklsf:
9468 case Intrinsic::s390_vpklsg:
9469 case Intrinsic::s390_vpklshs:
9470 case Intrinsic::s390_vpklsfs:
9471 case Intrinsic::s390_vpklsgs:
9473 SrcDemE = DemandedElts;
9476 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9479 case Intrinsic::s390_vuphb:
9480 case Intrinsic::s390_vuphh:
9481 case Intrinsic::s390_vuphf:
9482 case Intrinsic::s390_vuplhb:
9483 case Intrinsic::s390_vuplhh:
9484 case Intrinsic::s390_vuplhf:
9485 SrcDemE =
APInt(NumElts * 2, 0);
9488 case Intrinsic::s390_vuplb:
9489 case Intrinsic::s390_vuplhw:
9490 case Intrinsic::s390_vuplf:
9491 case Intrinsic::s390_vupllb:
9492 case Intrinsic::s390_vupllh:
9493 case Intrinsic::s390_vupllf:
9494 SrcDemE =
APInt(NumElts * 2, 0);
9497 case Intrinsic::s390_vpdi: {
9499 SrcDemE =
APInt(NumElts, 0);
9500 if (!DemandedElts[OpNo - 1])
9502 unsigned Mask =
Op.getConstantOperandVal(3);
9503 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9505 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9508 case Intrinsic::s390_vsldb: {
9510 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9511 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9512 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9513 unsigned NumSrc0Els = 16 - FirstIdx;
9514 SrcDemE =
APInt(NumElts, 0);
9516 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9519 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9524 case Intrinsic::s390_vperm:
9533 case SystemZISD::JOIN_DWORDS:
9535 SrcDemE =
APInt(1, 1);
9537 case SystemZISD::SELECT_CCMASK:
9538 SrcDemE = DemandedElts;
9549 const APInt &DemandedElts,
9564 const APInt &DemandedElts,
9566 unsigned Depth)
const {
9570 unsigned Tmp0, Tmp1;
9572 Known.Zero.setBitsFrom(2);
9575 EVT VT =
Op.getValueType();
9576 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9579 "KnownBits does not match VT in bitwidth");
9582 "DemandedElts does not match VT number of elements");
9584 unsigned Opcode =
Op.getOpcode();
9586 bool IsLogical =
false;
9587 unsigned Id =
Op.getConstantOperandVal(0);
9589 case Intrinsic::s390_vpksh:
9590 case Intrinsic::s390_vpksf:
9591 case Intrinsic::s390_vpksg:
9592 case Intrinsic::s390_vpkshs:
9593 case Intrinsic::s390_vpksfs:
9594 case Intrinsic::s390_vpksgs:
9595 case Intrinsic::s390_vpklsh:
9596 case Intrinsic::s390_vpklsf:
9597 case Intrinsic::s390_vpklsg:
9598 case Intrinsic::s390_vpklshs:
9599 case Intrinsic::s390_vpklsfs:
9600 case Intrinsic::s390_vpklsgs:
9601 case Intrinsic::s390_vpdi:
9602 case Intrinsic::s390_vsldb:
9603 case Intrinsic::s390_vperm:
9606 case Intrinsic::s390_vuplhb:
9607 case Intrinsic::s390_vuplhh:
9608 case Intrinsic::s390_vuplhf:
9609 case Intrinsic::s390_vupllb:
9610 case Intrinsic::s390_vupllh:
9611 case Intrinsic::s390_vupllf:
9614 case Intrinsic::s390_vuphb:
9615 case Intrinsic::s390_vuphh:
9616 case Intrinsic::s390_vuphf:
9617 case Intrinsic::s390_vuplb:
9618 case Intrinsic::s390_vuplhw:
9619 case Intrinsic::s390_vuplf: {
9634 case SystemZISD::JOIN_DWORDS:
9635 case SystemZISD::SELECT_CCMASK:
9638 case SystemZISD::REPLICATE: {
9661 if (
LHS == 1)
return 1;
9664 if (
RHS == 1)
return 1;
9665 unsigned Common = std::min(
LHS,
RHS);
9666 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9667 EVT VT =
Op.getValueType();
9669 if (SrcBitWidth > VTBits) {
9670 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9671 if (Common > SrcExtraBits)
9672 return (Common - SrcExtraBits);
9675 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9682 unsigned Depth)
const {
9683 if (
Op.getResNo() != 0)
9685 unsigned Opcode =
Op.getOpcode();
9687 unsigned Id =
Op.getConstantOperandVal(0);
9689 case Intrinsic::s390_vpksh:
9690 case Intrinsic::s390_vpksf:
9691 case Intrinsic::s390_vpksg:
9692 case Intrinsic::s390_vpkshs:
9693 case Intrinsic::s390_vpksfs:
9694 case Intrinsic::s390_vpksgs:
9695 case Intrinsic::s390_vpklsh:
9696 case Intrinsic::s390_vpklsf:
9697 case Intrinsic::s390_vpklsg:
9698 case Intrinsic::s390_vpklshs:
9699 case Intrinsic::s390_vpklsfs:
9700 case Intrinsic::s390_vpklsgs:
9701 case Intrinsic::s390_vpdi:
9702 case Intrinsic::s390_vsldb:
9703 case Intrinsic::s390_vperm:
9705 case Intrinsic::s390_vuphb:
9706 case Intrinsic::s390_vuphh:
9707 case Intrinsic::s390_vuphf:
9708 case Intrinsic::s390_vuplb:
9709 case Intrinsic::s390_vuplhw:
9710 case Intrinsic::s390_vuplf: {
9714 EVT VT =
Op.getValueType();
9724 case SystemZISD::SELECT_CCMASK:
9737 switch (
Op->getOpcode()) {
9738 case SystemZISD::PCREL_WRAPPER:
9739 case SystemZISD::PCREL_OFFSET:
9750 "Unexpected stack alignment");
9753 unsigned StackProbeSize =
9756 StackProbeSize &= ~(StackAlign - 1);
9757 return StackProbeSize ? StackProbeSize : StackAlign;
9796 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9798 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9804 if (miI ==
MBB->end()) {
9806 if (Succ->isLiveIn(SystemZ::CC))
9817 switch (
MI.getOpcode()) {
9818 case SystemZ::Select32:
9819 case SystemZ::Select64:
9820 case SystemZ::Select128:
9821 case SystemZ::SelectF32:
9822 case SystemZ::SelectF64:
9823 case SystemZ::SelectF128:
9824 case SystemZ::SelectVR32:
9825 case SystemZ::SelectVR64:
9826 case SystemZ::SelectVR128:
9858 for (
auto *
MI : Selects) {
9859 Register DestReg =
MI->getOperand(0).getReg();
9860 Register TrueReg =
MI->getOperand(1).getReg();
9861 Register FalseReg =
MI->getOperand(2).getReg();
9866 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9869 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9870 TrueReg = It->second.first;
9872 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9873 FalseReg = It->second.second;
9876 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9881 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9892 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9893 assert(TFL->hasReservedCallFrame(MF) &&
9894 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9899 uint32_t NumBytes =
MI.getOperand(0).getImm();
9904 MI.eraseFromParent();
9913 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9915 unsigned CCValid =
MI.getOperand(3).getImm();
9916 unsigned CCMask =
MI.getOperand(4).getImm();
9921 SmallVector<MachineInstr*, 8> Selects;
9922 SmallVector<MachineInstr*, 8> DbgValues;
9928 assert(NextMI.getOperand(3).getImm() == CCValid &&
9929 "Bad CCValid operands since CC was not redefined.");
9930 if (NextMI.getOperand(4).getImm() == CCMask ||
9931 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9937 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9938 NextMI.usesCustomInsertionHook())
9941 for (
auto *SelMI : Selects)
9942 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9946 if (NextMI.isDebugInstr()) {
9948 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9951 }
else if (User || ++
Count > 20)
9955 MachineInstr *LastMI = Selects.back();
9956 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9958 MachineBasicBlock *StartMBB =
MBB;
9988 for (
auto *SelMI : Selects)
9989 SelMI->eraseFromParent();
9992 for (
auto *DbgMI : DbgValues)
9993 MBB->
splice(InsertPos, StartMBB, DbgMI);
10004 unsigned StoreOpcode,
10005 unsigned STOCOpcode,
10006 bool Invert)
const {
10007 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10009 Register SrcReg =
MI.getOperand(0).getReg();
10010 MachineOperand
Base =
MI.getOperand(1);
10011 int64_t Disp =
MI.getOperand(2).getImm();
10012 Register IndexReg =
MI.getOperand(3).getReg();
10013 unsigned CCValid =
MI.getOperand(4).getImm();
10014 unsigned CCMask =
MI.getOperand(5).getImm();
10017 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10021 MachineMemOperand *MMO =
nullptr;
10022 for (
auto *
I :
MI.memoperands())
10023 if (
I->isStore()) {
10031 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10043 MI.eraseFromParent();
10051 MachineBasicBlock *StartMBB =
MBB;
10057 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10084 MI.eraseFromParent();
10094 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10102 MachineBasicBlock *StartMBB =
MBB;
10120 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10147 MI.eraseFromParent();
10158 bool Invert)
const {
10160 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10167 int64_t Disp =
MI.getOperand(2).getImm();
10169 Register BitShift =
MI.getOperand(4).getReg();
10170 Register NegBitShift =
MI.getOperand(5).getReg();
10171 unsigned BitSize =
MI.getOperand(6).getImm();
10175 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10176 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10177 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10187 MachineBasicBlock *StartMBB =
MBB;
10220 }
else if (BinOpcode)
10243 MI.eraseFromParent();
10254 unsigned KeepOldMask)
const {
10256 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10262 int64_t Disp =
MI.getOperand(2).getImm();
10264 Register BitShift =
MI.getOperand(4).getReg();
10265 Register NegBitShift =
MI.getOperand(5).getReg();
10266 unsigned BitSize =
MI.getOperand(6).getImm();
10270 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10271 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10272 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10283 MachineBasicBlock *StartMBB =
MBB;
10347 MI.eraseFromParent();
10357 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10363 int64_t Disp =
MI.getOperand(2).getImm();
10364 Register CmpVal =
MI.getOperand(3).getReg();
10365 Register OrigSwapVal =
MI.getOperand(4).getReg();
10366 Register BitShift =
MI.getOperand(5).getReg();
10367 Register NegBitShift =
MI.getOperand(6).getReg();
10368 int64_t BitSize =
MI.getOperand(7).getImm();
10374 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10375 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10376 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10377 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10389 MachineBasicBlock *StartMBB =
MBB;
10461 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10464 MI.eraseFromParent();
10472 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10477 .
add(
MI.getOperand(1))
10478 .
addImm(SystemZ::subreg_h64)
10479 .
add(
MI.getOperand(2))
10480 .
addImm(SystemZ::subreg_l64);
10481 MI.eraseFromParent();
10490 bool ClearEven)
const {
10492 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10514 MI.eraseFromParent();
10521 unsigned Opcode,
bool IsMemset)
const {
10523 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10528 uint64_t DestDisp =
MI.getOperand(1).getImm();
10533 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10536 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10546 SrcDisp =
MI.getOperand(3).getImm();
10548 SrcBase = DestBase;
10549 SrcDisp = DestDisp++;
10550 foldDisplIfNeeded(DestBase, DestDisp);
10553 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10554 bool IsImmForm = LengthMO.
isImm();
10555 bool IsRegForm = !IsImmForm;
10558 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10560 MachineOperand DBase, uint64_t DDisp,
10561 MachineOperand
SBase, uint64_t SDisp,
10562 unsigned Length) ->
void {
10566 if (ByteMO.
isImm())
10581 bool NeedsLoop =
false;
10582 uint64_t ImmLength = 0;
10583 Register LenAdjReg = SystemZ::NoRegister;
10585 ImmLength = LengthMO.
getImm();
10586 ImmLength += IsMemset ? 2 : 1;
10587 if (ImmLength == 0) {
10588 MI.eraseFromParent();
10591 if (Opcode == SystemZ::CLC) {
10592 if (ImmLength > 3 * 256)
10602 }
else if (ImmLength > 6 * 256)
10610 LenAdjReg = LengthMO.
getReg();
10615 MachineBasicBlock *EndMBB =
10616 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10624 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10634 auto loadZeroAddress = [&]() -> MachineOperand {
10639 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10640 DestBase = loadZeroAddress();
10641 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10642 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10644 MachineBasicBlock *StartMBB =
nullptr;
10645 MachineBasicBlock *LoopMBB =
nullptr;
10646 MachineBasicBlock *NextMBB =
nullptr;
10647 MachineBasicBlock *DoneMBB =
nullptr;
10648 MachineBasicBlock *AllDoneMBB =
nullptr;
10652 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10661 RC = &SystemZ::GR64BitRegClass;
10689 MBB = MemsetOneCheckMBB;
10700 MBB = MemsetOneMBB;
10732 if (EndMBB && !ImmLength)
10754 if (!HaveSingleBase)
10761 if (Opcode == SystemZ::MVC)
10788 if (!HaveSingleBase)
10811 Register RemDestReg = HaveSingleBase ? RemSrcReg
10816 if (!HaveSingleBase)
10824 MachineInstrBuilder EXRL_MIB =
10832 if (Opcode != SystemZ::MVC) {
10842 while (ImmLength > 0) {
10843 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10846 foldDisplIfNeeded(DestBase, DestDisp);
10847 foldDisplIfNeeded(SrcBase, SrcDisp);
10848 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10849 DestDisp += ThisLength;
10850 SrcDisp += ThisLength;
10851 ImmLength -= ThisLength;
10854 if (EndMBB && ImmLength > 0) {
10870 MI.eraseFromParent();
10879 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10883 uint64_t End1Reg =
MI.getOperand(0).getReg();
10884 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10885 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10886 uint64_t CharReg =
MI.getOperand(3).getReg();
10893 MachineBasicBlock *StartMBB =
MBB;
10929 MI.eraseFromParent();
10936 bool NoFloat)
const {
10938 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10939 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10942 MI.setDesc(
TII->get(Opcode));
10946 uint64_t Control =
MI.getOperand(2).getImm();
10947 static const unsigned GPRControlBit[16] = {
10948 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10949 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10951 Control |= GPRControlBit[15];
10952 if (TFI->
hasFP(MF))
10953 Control |= GPRControlBit[11];
10954 MI.getOperand(2).setImm(Control);
10957 for (
int I = 0;
I < 16;
I++) {
10958 if ((Control & GPRControlBit[
I]) == 0) {
10965 if (!NoFloat && (Control & 4) != 0) {
10966 if (Subtarget.hasVector()) {
10983 MachineRegisterInfo *MRI = &MF.
getRegInfo();
10984 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10987 Register SrcReg =
MI.getOperand(0).getReg();
10998 MI.eraseFromParent();
11006 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11007 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11010 Register DstReg =
MI.getOperand(0).getReg();
11011 Register SizeReg =
MI.getOperand(2).getReg();
11013 MachineBasicBlock *StartMBB =
MBB;
11089 MI.eraseFromParent();
11093SDValue SystemZTargetLowering::
11096 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11108 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11113 .
addImm(
MI.getOperand(1).getImm());
11114 MI.eraseFromParent();
11120 switch (
MI.getOpcode()) {
11121 case SystemZ::ADJCALLSTACKDOWN:
11122 case SystemZ::ADJCALLSTACKUP:
11123 return emitAdjCallStack(
MI,
MBB);
11125 case SystemZ::Select32:
11126 case SystemZ::Select64:
11127 case SystemZ::Select128:
11128 case SystemZ::SelectF32:
11129 case SystemZ::SelectF64:
11130 case SystemZ::SelectF128:
11131 case SystemZ::SelectVR32:
11132 case SystemZ::SelectVR64:
11133 case SystemZ::SelectVR128:
11134 return emitSelect(
MI,
MBB);
11136 case SystemZ::CondStore8Mux:
11137 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11138 case SystemZ::CondStore8MuxInv:
11139 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11140 case SystemZ::CondStore16Mux:
11141 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11142 case SystemZ::CondStore16MuxInv:
11143 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11144 case SystemZ::CondStore32Mux:
11145 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11146 case SystemZ::CondStore32MuxInv:
11147 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11148 case SystemZ::CondStore8:
11149 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11150 case SystemZ::CondStore8Inv:
11151 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11152 case SystemZ::CondStore16:
11153 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11154 case SystemZ::CondStore16Inv:
11155 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11156 case SystemZ::CondStore32:
11157 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11158 case SystemZ::CondStore32Inv:
11159 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11160 case SystemZ::CondStore64:
11161 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11162 case SystemZ::CondStore64Inv:
11163 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11164 case SystemZ::CondStoreF32:
11165 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11166 case SystemZ::CondStoreF32Inv:
11167 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11168 case SystemZ::CondStoreF64:
11169 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11170 case SystemZ::CondStoreF64Inv:
11171 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11173 case SystemZ::SCmp128Hi:
11174 return emitICmp128Hi(
MI,
MBB,
false);
11175 case SystemZ::UCmp128Hi:
11176 return emitICmp128Hi(
MI,
MBB,
true);
11178 case SystemZ::PAIR128:
11179 return emitPair128(
MI,
MBB);
11180 case SystemZ::AEXT128:
11181 return emitExt128(
MI,
MBB,
false);
11182 case SystemZ::ZEXT128:
11183 return emitExt128(
MI,
MBB,
true);
11185 case SystemZ::ATOMIC_SWAPW:
11186 return emitAtomicLoadBinary(
MI,
MBB, 0);
11188 case SystemZ::ATOMIC_LOADW_AR:
11189 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11190 case SystemZ::ATOMIC_LOADW_AFI:
11191 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11193 case SystemZ::ATOMIC_LOADW_SR:
11194 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11196 case SystemZ::ATOMIC_LOADW_NR:
11197 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11198 case SystemZ::ATOMIC_LOADW_NILH:
11199 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11201 case SystemZ::ATOMIC_LOADW_OR:
11202 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11203 case SystemZ::ATOMIC_LOADW_OILH:
11204 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11206 case SystemZ::ATOMIC_LOADW_XR:
11207 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11208 case SystemZ::ATOMIC_LOADW_XILF:
11209 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11211 case SystemZ::ATOMIC_LOADW_NRi:
11212 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11213 case SystemZ::ATOMIC_LOADW_NILHi:
11214 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11216 case SystemZ::ATOMIC_LOADW_MIN:
11218 case SystemZ::ATOMIC_LOADW_MAX:
11220 case SystemZ::ATOMIC_LOADW_UMIN:
11222 case SystemZ::ATOMIC_LOADW_UMAX:
11225 case SystemZ::ATOMIC_CMP_SWAPW:
11226 return emitAtomicCmpSwapW(
MI,
MBB);
11227 case SystemZ::MVCImm:
11228 case SystemZ::MVCReg:
11229 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11230 case SystemZ::NCImm:
11231 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11232 case SystemZ::OCImm:
11233 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11234 case SystemZ::XCImm:
11235 case SystemZ::XCReg:
11236 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11237 case SystemZ::CLCImm:
11238 case SystemZ::CLCReg:
11239 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11240 case SystemZ::MemsetImmImm:
11241 case SystemZ::MemsetImmReg:
11242 case SystemZ::MemsetRegImm:
11243 case SystemZ::MemsetRegReg:
11244 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11245 case SystemZ::CLSTLoop:
11246 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11247 case SystemZ::MVSTLoop:
11248 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11249 case SystemZ::SRSTLoop:
11250 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11251 case SystemZ::TBEGIN:
11252 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11253 case SystemZ::TBEGIN_nofloat:
11254 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11255 case SystemZ::TBEGINC:
11256 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11257 case SystemZ::LTEBRCompare_Pseudo:
11258 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11259 case SystemZ::LTDBRCompare_Pseudo:
11260 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11261 case SystemZ::LTXBRCompare_Pseudo:
11262 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11264 case SystemZ::PROBED_ALLOCA:
11265 return emitProbedAlloca(
MI,
MBB);
11266 case SystemZ::EH_SjLj_SetJmp:
11268 case SystemZ::EH_SjLj_LongJmp:
11271 case TargetOpcode::STACKMAP:
11272 case TargetOpcode::PATCHPOINT:
11275 case SystemZ::MOV_STACKGUARD_DAG:
11276 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11278 case SystemZ::CMP_STACKGUARD_DAG:
11279 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11289SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11290 if (VT == MVT::Untyped)
11291 return &SystemZ::ADDR128BitRegClass;
11317 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11337 EVT VT =
Op.getValueType();
11338 Op =
Op.getOperand(0);
11339 EVT OpVT =
Op.getValueType();
11341 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11352 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11372 const AttributeList &Attrs =
F->getAttributes();
11373 if (Attrs.hasRetAttrs())
11374 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11375 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11376 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11379 OS << *FT->getParamType(
I);
11381 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11388bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11389 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11390 if (Itr == IsInternalCache.end())
11391 Itr = IsInternalCache
11392 .insert(std::pair<const Function *, bool>(
11395 return Itr->second;
11398void SystemZTargetLowering::
11406 bool IsInternal =
false;
11407 const Function *CalleeFn =
nullptr;
11410 IsInternal = isInternal(CalleeFn);
11411 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11412 errs() <<
"ERROR: Missing extension attribute of passed "
11413 <<
"value in call to function:\n" <<
"Callee: ";
11414 if (CalleeFn !=
nullptr)
11418 errs() <<
"Caller: ";
11424void SystemZTargetLowering::
11432 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11433 errs() <<
"ERROR: Missing extension attribute of returned "
11434 <<
"value from function:\n";
11442bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11444 if (!Subtarget.isTargetELF())
11453 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11454 MVT VT = Outs[i].VT;
11455 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11458 "Unexpected integer argument VT.");
11459 if (VT == MVT::i32 &&
11470 StringRef GuardMode = M.getStackProtectorGuard();
11473 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.
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, in exactly one operand.
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.
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).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
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
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...
CondMergingParams getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs, const Function *F) const override
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.
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.
@ Known
Known to have no common set bits.
@ 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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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)
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...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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.
MCRegisterClass TargetRegisterClass
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 intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
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.