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}) {
722 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
723 MVT::v4f32, MVT::v2f64 }) {
734 if (!Subtarget.hasVectorEnhancements1()) {
740 if (Subtarget.hasVectorEnhancements1())
750 if (Subtarget.hasVectorEnhancements1()) {
762 if (!Subtarget.hasVector()) {
773 if (Subtarget.isTargetzOS()) {
838 return Subtarget.hasSoftFloat();
843 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
845 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16)) {
846 IntermediateVT = RegisterVT = MVT::v8f16;
847 return NumIntermediates =
851 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
863 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
871 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
898 return Subtarget.hasVectorEnhancements1();
911 if (!Subtarget.hasVector() ||
912 (isFP128 && !Subtarget.hasVectorEnhancements1()))
921 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
928 Opcode = SystemZISD::BYTE_MASK;
934 if (SplatBitSize > 64)
941 OpVals.push_back(((
unsigned) SignedValue));
942 Opcode = SystemZISD::REPLICATE;
949 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start, End)) {
953 OpVals.push_back(Start - (64 - SplatBitSize));
954 OpVals.push_back(End - (64 - SplatBitSize));
955 Opcode = SystemZISD::ROTATE_MASK;
967 uint64_t SplatBitsZ = SplatBits.getZExtValue();
968 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
980 return TryValue(SplatBitsZ | Middle);
989 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
995 unsigned HalfSize = Width / 2;
1000 if (HighValue != LowValue || 8 > HalfSize)
1003 SplatBits = HighValue;
1007 SplatBitSize = Width;
1015 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1019 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1024 bool ForCodeSize)
const {
1026 if (Imm.isZero() || Imm.isNegZero())
1047 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1053 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1106 const int64_t FPOffset = 0;
1127 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1128 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1131 .
addReg(SpecialRegs->getFramePointerRegister())
1139 .
addReg(SpecialRegs->getStackPointerRegister())
1150 .
addReg(SpecialRegs->getStackPointerRegister())
1151 .
addImm(TFL->getBackchainOffset(*MF))
1162 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1166 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1187 MI.eraseFromParent();
1203 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1206 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1213 const int64_t FPOffset = 0;
1225 SpecialRegs->getFramePointerRegister())
1247 SpecialRegs->getStackPointerRegister())
1256 .
addReg(SpecialRegs->getStackPointerRegister())
1257 .
addImm(TFL->getBackchainOffset(*MF))
1263 MI.eraseFromParent();
1294 if (Subtarget.hasInterlockedAccess1() &&
1327 EVT VT =
Y.getValueType();
1330 if (VT == MVT::i32 || VT == MVT::i64)
1331 return Subtarget.hasMiscellaneousExtensions3();
1334 if (VT.
isVector() || VT == MVT::i128)
1335 return Subtarget.hasVector();
1363 bool MVC = Ty->isIntegerTy(8);
1369static AddressingMode
1372 switch (
II->getIntrinsicID()) {
1374 case Intrinsic::memset:
1375 case Intrinsic::memmove:
1376 case Intrinsic::memcpy:
1383 if (SingleUser->getParent() ==
I->getParent()) {
1386 if (
C->getBitWidth() <= 64 &&
1396 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1410 I->getOperand(0)->getType());
1412 bool IsVectorAccess = MemAccessTy->isVectorTy();
1417 Value *DataOp =
I->getOperand(0);
1419 IsVectorAccess =
true;
1425 User *LoadUser = *
I->user_begin();
1427 IsVectorAccess =
true;
1430 if (IsFPAccess || IsVectorAccess)
1449 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1459 return AM.
Scale == 0;
1466 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1467 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1468 const AttributeList &FuncAttributes,
EVT *LargestVT)
const {
1471 "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
1473 if (
Op.isZeroMemset())
1476 const int MVCFastLen = 16;
1479 if (
Op.isMemcpy() &&
Op.size() <= MVCFastLen)
1481 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1485 if ((
Op.size() >= 16 && !
Op.isAligned(
Align(8))) ||
1486 (
Op.size() >= 25 &&
Op.size() <= 31))
1490 Context, MemOps, Limit,
Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1495 const AttributeList &FuncAttributes)
const {
1496 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1500 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1502 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1504 return FromBits > ToBits;
1512 return FromBits > ToBits;
1521 if (Constraint.
size() == 1) {
1522 switch (Constraint[0]) {
1548 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1549 switch (Constraint[1]) {
1560 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1570 Value *CallOperandVal = Info.CallOperandVal;
1573 if (!CallOperandVal)
1577 switch (*Constraint) {
1596 if (Subtarget.hasVector())
1627 if (
C->getZExtValue() == 0x7fffffff)
1637static std::pair<unsigned, const TargetRegisterClass *>
1639 const unsigned *Map,
unsigned Size) {
1640 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1641 if (isdigit(Constraint[2])) {
1646 return std::make_pair(Map[Index], RC);
1648 return std::make_pair(0U,
nullptr);
1651std::pair<unsigned, const TargetRegisterClass *>
1654 if (Constraint.
size() == 1) {
1656 switch (Constraint[0]) {
1661 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1663 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1664 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1668 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1669 else if (VT == MVT::i128)
1670 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1671 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1674 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1679 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1681 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1683 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1684 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1689 if (Subtarget.hasVector()) {
1691 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1693 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1695 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1696 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1705 auto getVTSizeInBits = [&VT]() {
1713 if (Constraint[1] ==
'r') {
1714 if (getVTSizeInBits() == 32)
1717 if (getVTSizeInBits() == 128)
1723 if (Constraint[1] ==
'f') {
1725 return std::make_pair(
1727 if (getVTSizeInBits() == 16)
1730 if (getVTSizeInBits() == 32)
1733 if (getVTSizeInBits() == 128)
1739 if (Constraint[1] ==
'v') {
1740 if (!Subtarget.hasVector())
1741 return std::make_pair(
1743 if (getVTSizeInBits() == 16)
1746 if (getVTSizeInBits() == 32)
1749 if (getVTSizeInBits() == 64)
1755 if (Constraint[1] ==
'@') {
1756 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1757 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1770 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1771 : SystemZ::NoRegister)
1773 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1780 const Constant *PersonalityFn)
const {
1781 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1785 const Constant *PersonalityFn)
const {
1786 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1801 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1805 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1806 OpInfo.ConstraintVT.getSizeInBits() < 8)
1821 if (Constraint.
size() == 1) {
1822 switch (Constraint[0]) {
1827 Op.getValueType()));
1834 Op.getValueType()));
1841 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1848 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1853 if (
C->getZExtValue() == 0x7fffffff)
1855 Op.getValueType()));
1866#define GET_CALLING_CONV_IMPL
1867#include "SystemZGenCallingConv.inc"
1871 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1877 Type *ToType)
const {
1940 if (BitCastToType == MVT::v2i64)
1967 MVT::Untyped,
Hi,
Lo);
1991 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1993 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2004 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
2005 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2016template <
class ArgTy>
2019 MVT &PartVT,
unsigned &NumParts) {
2020 if (!Args[
I].Flags.isSplit())
2024 PartVT = ArgLocs[
I].getValVT();
2026 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2027 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2028 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2030 if (Args[PartIdx].Flags.isSplitEnd())
2054 unsigned NumFixedGPRs = 0;
2055 unsigned NumFixedFPRs = 0;
2056 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2069 RC = &SystemZ::GR32BitRegClass;
2073 RC = &SystemZ::GR64BitRegClass;
2077 RC = &SystemZ::FP16BitRegClass;
2081 RC = &SystemZ::FP32BitRegClass;
2085 RC = &SystemZ::FP64BitRegClass;
2089 RC = &SystemZ::FP128BitRegClass;
2098 RC = &SystemZ::VR128BitRegClass;
2112 if (Subtarget.isTargetXPLINK64()) {
2115 ArgSPOffset += XPRegs.getCallFrameSize();
2126 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2130 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2144 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2147 unsigned PartOffset = Ins[
I].PartOffset;
2152 assert(PartOffset &&
"Offset should be non-zero.");
2159 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2165 Subtarget.getSpecialRegisters());
2171 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2176 if (IsVarArg && Subtarget.isTargetELF()) {
2189 int64_t RegSaveOffset =
2204 &SystemZ::FP64BitRegClass);
2216 if (Subtarget.isTargetXPLINK64()) {
2221 Subtarget.getSpecialRegisters());
2222 MRI.
addLiveIn(Regs->getADARegister(), ADAvReg);
2234 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2241 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2243 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2250 unsigned Offset,
bool LoadAdr =
false) {
2273 bool LoadAddr =
false;
2295 unsigned ADADelta = 0;
2296 unsigned EPADelta = 8;
2302 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2303 G->getGlobal()->hasPrivateLinkage());
2310 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2356 if (Subtarget.isTargetXPLINK64())
2360 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2364 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2383 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2391 unsigned NumParts = 1;
2395 SlotVT = Outs[
I].VT;
2402 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2405 assert(Outs[
I].PartOffset == 0);
2406 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2409 unsigned PartOffset = Outs[
I].PartOffset;
2415 assert(PartOffset &&
"Offset should be non-zero.");
2417 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2419 ArgValue = SpillSlot;
2436 if (!StackPtr.getNode())
2443 else if (VA.
getLocVT() == MVT::f16)
2456 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2460 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2466 if (!MemOpChains.
empty())
2474 if (Subtarget.isTargetXPLINK64()) {
2479 ->getAddressOfCalleeRegister();
2482 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2489 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2492 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2493 }
else if (IsTailCall) {
2496 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2501 for (
const auto &[Reg,
N] : RegsToPass) {
2508 Ops.push_back(Chain);
2509 Ops.push_back(Callee);
2513 for (
const auto &[Reg,
N] : RegsToPass)
2518 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2519 assert(Mask &&
"Missing call preserved mask for calling convention");
2524 Ops.push_back(Glue);
2533 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2543 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2550 VA.getLocVT(), Glue);
2567 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2569 Args.reserve(
Ops.size());
2575 Entry.IsZExt = !Entry.IsSExt;
2576 Args.push_back(Entry);
2587 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2598 const Type *RetTy)
const {
2601 for (
auto &Out : Outs)
2602 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2606 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2607 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2619 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2627 if (RetLocs.
empty())
2628 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2637 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2659 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2666 unsigned &CCValid) {
2667 unsigned Id =
Op.getConstantOperandVal(1);
2669 case Intrinsic::s390_tbegin:
2670 Opcode = SystemZISD::TBEGIN;
2674 case Intrinsic::s390_tbegin_nofloat:
2675 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2679 case Intrinsic::s390_tend:
2680 Opcode = SystemZISD::TEND;
2693 unsigned Id =
Op.getConstantOperandVal(0);
2695 case Intrinsic::s390_vpkshs:
2696 case Intrinsic::s390_vpksfs:
2697 case Intrinsic::s390_vpksgs:
2698 Opcode = SystemZISD::PACKS_CC;
2702 case Intrinsic::s390_vpklshs:
2703 case Intrinsic::s390_vpklsfs:
2704 case Intrinsic::s390_vpklsgs:
2705 Opcode = SystemZISD::PACKLS_CC;
2709 case Intrinsic::s390_vceqbs:
2710 case Intrinsic::s390_vceqhs:
2711 case Intrinsic::s390_vceqfs:
2712 case Intrinsic::s390_vceqgs:
2713 case Intrinsic::s390_vceqqs:
2714 Opcode = SystemZISD::VICMPES;
2718 case Intrinsic::s390_vchbs:
2719 case Intrinsic::s390_vchhs:
2720 case Intrinsic::s390_vchfs:
2721 case Intrinsic::s390_vchgs:
2722 case Intrinsic::s390_vchqs:
2723 Opcode = SystemZISD::VICMPHS;
2727 case Intrinsic::s390_vchlbs:
2728 case Intrinsic::s390_vchlhs:
2729 case Intrinsic::s390_vchlfs:
2730 case Intrinsic::s390_vchlgs:
2731 case Intrinsic::s390_vchlqs:
2732 Opcode = SystemZISD::VICMPHLS;
2736 case Intrinsic::s390_vtm:
2737 Opcode = SystemZISD::VTM;
2741 case Intrinsic::s390_vfaebs:
2742 case Intrinsic::s390_vfaehs:
2743 case Intrinsic::s390_vfaefs:
2744 Opcode = SystemZISD::VFAE_CC;
2748 case Intrinsic::s390_vfaezbs:
2749 case Intrinsic::s390_vfaezhs:
2750 case Intrinsic::s390_vfaezfs:
2751 Opcode = SystemZISD::VFAEZ_CC;
2755 case Intrinsic::s390_vfeebs:
2756 case Intrinsic::s390_vfeehs:
2757 case Intrinsic::s390_vfeefs:
2758 Opcode = SystemZISD::VFEE_CC;
2762 case Intrinsic::s390_vfeezbs:
2763 case Intrinsic::s390_vfeezhs:
2764 case Intrinsic::s390_vfeezfs:
2765 Opcode = SystemZISD::VFEEZ_CC;
2769 case Intrinsic::s390_vfenebs:
2770 case Intrinsic::s390_vfenehs:
2771 case Intrinsic::s390_vfenefs:
2772 Opcode = SystemZISD::VFENE_CC;
2776 case Intrinsic::s390_vfenezbs:
2777 case Intrinsic::s390_vfenezhs:
2778 case Intrinsic::s390_vfenezfs:
2779 Opcode = SystemZISD::VFENEZ_CC;
2783 case Intrinsic::s390_vistrbs:
2784 case Intrinsic::s390_vistrhs:
2785 case Intrinsic::s390_vistrfs:
2786 Opcode = SystemZISD::VISTR_CC;
2790 case Intrinsic::s390_vstrcbs:
2791 case Intrinsic::s390_vstrchs:
2792 case Intrinsic::s390_vstrcfs:
2793 Opcode = SystemZISD::VSTRC_CC;
2797 case Intrinsic::s390_vstrczbs:
2798 case Intrinsic::s390_vstrczhs:
2799 case Intrinsic::s390_vstrczfs:
2800 Opcode = SystemZISD::VSTRCZ_CC;
2804 case Intrinsic::s390_vstrsb:
2805 case Intrinsic::s390_vstrsh:
2806 case Intrinsic::s390_vstrsf:
2807 Opcode = SystemZISD::VSTRS_CC;
2811 case Intrinsic::s390_vstrszb:
2812 case Intrinsic::s390_vstrszh:
2813 case Intrinsic::s390_vstrszf:
2814 Opcode = SystemZISD::VSTRSZ_CC;
2818 case Intrinsic::s390_vfcedbs:
2819 case Intrinsic::s390_vfcesbs:
2820 Opcode = SystemZISD::VFCMPES;
2824 case Intrinsic::s390_vfchdbs:
2825 case Intrinsic::s390_vfchsbs:
2826 Opcode = SystemZISD::VFCMPHS;
2830 case Intrinsic::s390_vfchedbs:
2831 case Intrinsic::s390_vfchesbs:
2832 Opcode = SystemZISD::VFCMPHES;
2836 case Intrinsic::s390_vftcidb:
2837 case Intrinsic::s390_vftcisb:
2838 Opcode = SystemZISD::VFTCI;
2842 case Intrinsic::s390_tdc:
2843 Opcode = SystemZISD::TDC;
2856 unsigned NumOps =
Op.getNumOperands();
2859 Ops.push_back(
Op.getOperand(0));
2861 Ops.push_back(
Op.getOperand(
I));
2863 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2877 unsigned NumOps =
Op.getNumOperands();
2883 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2884 "Unhandled intrinsic with f16 operand.");
2887 Ops.push_back(CurrOper);
2901 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2902 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2903 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2929 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2932 int64_t
Value = ConstOp1->getSExtValue();
2948 if (!
C.Op0.hasOneUse() ||
2955 unsigned NumBits =
Load->getMemoryVT().getSizeInBits();
2956 if ((NumBits != 8 && NumBits != 16) ||
2957 NumBits !=
Load->getMemoryVT().getStoreSizeInBits())
2963 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2966 uint64_t Mask = (1 << NumBits) - 1;
2969 int64_t SignedValue = ConstOp1->getSExtValue();
2976 }
else if (NumBits == 8) {
3002 if (
C.Op0.getValueType() != MVT::i32 ||
3003 Load->getExtensionType() != ExtType) {
3005 Load->getBasePtr(),
Load->getPointerInfo(),
3006 Load->getMemoryVT(),
Load->getAlign(),
3007 Load->getMemOperand()->getFlags());
3013 if (
C.Op1.getValueType() != MVT::i32 ||
3014 Value != ConstOp1->getZExtValue())
3024 if (
Load->getMemoryVT() == MVT::i8)
3027 switch (
Load->getExtensionType()) {
3045 if (
C.Op0.isMachineOpcode() &&
3046 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3050 if (
C.Op0.getValueType() == MVT::i128)
3052 if (
C.Op0.getValueType() == MVT::f128)
3064 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3093 unsigned Opcode0 =
C.Op0.getOpcode();
3100 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3115 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3116 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3138 if (C1 && C1->isZero()) {
3157 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3160 if (C1 && C1->getZExtValue() == 32) {
3161 SDValue ShlOp0 =
C.Op0.getOperand(0);
3180 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3183 C.Op1->getAsZExtVal() == 0) {
3185 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3186 C.Op0.getValueSizeInBits().getFixedValue()) {
3187 unsigned Type = L->getExtensionType();
3190 C.Op0 =
C.Op0.getOperand(0);
3206 if (
C.Opcode != SystemZISD::ICMP)
3216 if (!
C.Op1.isMachineOpcode() ||
3217 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3222 C.Opcode = SystemZISD::CMP_STACKGUARD;
3233 uint64_t Amount = Shift->getZExtValue();
3234 if (Amount >=
N.getValueSizeInBits())
3249 unsigned ICmpType) {
3250 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3272 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3278 if (EffectivelyUnsigned && CmpVal <
Low) {
3286 if (CmpVal == Mask) {
3292 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3298 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3306 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3312 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3341 if (
C.Op0.getValueType() == MVT::i128) {
3347 if (Mask && Mask->getAPIntValue() == 0) {
3348 C.Opcode = SystemZISD::VTM;
3365 uint64_t CmpVal = ConstOp1->getZExtValue();
3372 NewC.Op0 =
C.Op0.getOperand(0);
3373 NewC.Op1 =
C.Op0.getOperand(1);
3377 MaskVal = Mask->getZExtValue();
3397 MaskVal = -(CmpVal & -CmpVal);
3406 unsigned NewCCMask, ShiftVal;
3410 (MaskVal >> ShiftVal != 0) &&
3411 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3413 MaskVal >> ShiftVal,
3417 MaskVal >>= ShiftVal;
3421 (MaskVal << ShiftVal != 0) &&
3422 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3424 MaskVal << ShiftVal,
3428 MaskVal <<= ShiftVal;
3437 C.Opcode = SystemZISD::TM;
3439 if (Mask && Mask->getZExtValue() == MaskVal)
3444 C.CCMask = NewCCMask;
3450 if (
C.Opcode != SystemZISD::ICMP)
3452 if (
C.Op0.getValueType() != MVT::i128)
3463 Src = Src.getOperand(0);
3466 unsigned Opcode = 0;
3467 if (Src.hasOneUse()) {
3468 switch (Src.getOpcode()) {
3469 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3470 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3471 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3472 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3473 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3474 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3480 C.Op0 = Src->getOperand(0);
3481 C.Op1 = Src->getOperand(1);
3485 C.CCMask ^=
C.CCValid;
3497 C.Opcode = SystemZISD::VICMPES;
3509 bool Swap =
false, Invert =
false;
3521 C.Opcode = SystemZISD::UCMP128HI;
3523 C.Opcode = SystemZISD::SCMP128HI;
3528 C.CCMask ^=
C.CCValid;
3539 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3542 if ((~
Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3545 C.Op0 =
C.Op0.getOperand(0);
3557 C.CCValid = CCValid;
3560 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3563 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3567 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3570 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3574 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3577 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3580 C.CCMask &= CCValid;
3588 bool IsSignaling =
false) {
3591 unsigned Opcode, CCValid;
3603 Comparison
C(CmpOp0, CmpOp1, Chain);
3605 if (
C.Op0.getValueType().isFloatingPoint()) {
3608 C.Opcode = SystemZISD::FCMP;
3609 else if (!IsSignaling)
3610 C.Opcode = SystemZISD::STRICT_FCMP;
3612 C.Opcode = SystemZISD::STRICT_FCMPS;
3617 C.Opcode = SystemZISD::ICMP;
3653 if (!
C.Op1.getNode()) {
3654 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3655 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3657 switch (
C.Op0.getOpcode()) {
3668 if (
C.Opcode == SystemZISD::ICMP)
3669 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3671 if (
C.Opcode == SystemZISD::TM) {
3674 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3677 if (
C.Opcode == SystemZISD::VICMPES ||
3678 C.Opcode == SystemZISD::VICMPHS ||
3679 C.Opcode == SystemZISD::VICMPHLS ||
3680 C.Opcode == SystemZISD::VFCMPES ||
3681 C.Opcode == SystemZISD::VFCMPHS ||
3682 C.Opcode == SystemZISD::VFCMPHES) {
3683 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3690 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3692 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3701 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3702 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3727 unsigned CCValid,
unsigned CCMask) {
3732 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3810 int Mask[] = { Start, -1, Start + 1, -1 };
3814 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3816 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3830 !Subtarget.hasVectorEnhancements1()) {
3836 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3849 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3852 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3853 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3855 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3868 bool IsSignaling)
const {
3871 assert (!IsSignaling || Chain);
3874 bool Invert =
false;
3882 assert(IsFP &&
"Unexpected integer comparison");
3884 DL, VT, CmpOp1, CmpOp0, Chain);
3886 DL, VT, CmpOp0, CmpOp1, Chain);
3890 LT.getValue(1),
GE.getValue(1));
3899 assert(IsFP &&
"Unexpected integer comparison");
3901 DL, VT, CmpOp1, CmpOp0, Chain);
3903 DL, VT, CmpOp0, CmpOp1, Chain);
3907 LT.getValue(1),
GT.getValue(1));
3928 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3932 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3937 Chain =
Cmp.getValue(1);
3945 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3958 EVT VT =
Op.getValueType();
3960 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3969 bool IsSignaling)
const {
3975 EVT VT =
Op.getNode()->getValueType(0);
3977 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3978 Chain, IsSignaling);
4000 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4034 C.CCMask ^=
C.CCValid;
4042 Op = SystemZISD::VICMPE;
4046 Op = SystemZISD::VICMPHL;
4048 Op = SystemZISD::VICMPH;
4087 C.Op1->getAsZExtVal() == 0) {
4094 if (Subtarget.hasVectorEnhancements3() &&
4095 C.Opcode == SystemZISD::ICMP &&
4096 C.Op0.getValueType() == MVT::i128 &&
4106 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4112 const GlobalValue *GV =
Node->getGlobal();
4118 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4121 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4140 }
else if (Subtarget.isTargetELF()) {
4145 }
else if (Subtarget.isTargetzOS()) {
4176 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4181 Ops.push_back(Chain);
4183 Node->getValueType(0),
4192 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4193 const uint32_t *
Mask =
4195 assert(Mask &&
"Missing call preserved mask for calling convention");
4199 Ops.push_back(Glue);
4202 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4210SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4234 const GlobalValue *GV =
Node->getGlobal();
4242 SDValue TP = lowerThreadPointer(
DL, DAG);
4249 SystemZConstantPoolValue *CPV =
4258 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4264 SystemZConstantPoolValue *CPV =
4273 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4278 SystemZMachineFunctionInfo* MFI =
4307 SystemZConstantPoolValue *CPV =
4341 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4358 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4363 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4365 MachineFrameInfo &MFI = MF.getFrameInfo();
4369 unsigned Depth =
Op.getConstantOperandVal(0);
4376 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4381 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4387 MachinePointerInfo());
4402 unsigned Depth =
Op.getConstantOperandVal(0);
4407 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4410 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4411 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4412 int Offset = TFL->getReturnAddressOffset(MF);
4416 MachinePointerInfo());
4421 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4423 &SystemZ::GR64BitRegClass);
4431 EVT InVT =
In.getValueType();
4432 EVT ResVT =
Op.getValueType();
4440 LoadN->getBasePtr(), LoadN->getMemOperand());
4446 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4448 if (Subtarget.hasHighWord()) {
4452 MVT::i64,
SDValue(U64, 0), In);
4460 DL, MVT::f32, Out64);
4462 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4465 MVT::f64,
SDValue(U64, 0), In);
4467 if (Subtarget.hasHighWord())
4480 if (Subtarget.isTargetXPLINK64())
4481 return lowerVASTART_XPLINK(
Op, DAG);
4483 return lowerVASTART_ELF(
Op, DAG);
4489 SystemZMachineFunctionInfo *FuncInfo =
4490 MF.
getInfo<SystemZMachineFunctionInfo>();
4500 MachinePointerInfo(SV));
4506 SystemZMachineFunctionInfo *FuncInfo =
4507 MF.
getInfo<SystemZMachineFunctionInfo>();
4516 const unsigned NumFields = 4;
4527 for (
unsigned I = 0;
I < NumFields; ++
I) {
4532 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4533 MachinePointerInfo(SV,
Offset));
4553 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4554 MachinePointerInfo(SrcSV));
4558SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4560 if (Subtarget.isTargetXPLINK64())
4561 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4563 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4567SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4569 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4579 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4582 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4583 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4589 if (ExtraAlignSpace)
4593 bool IsSigned =
false;
4594 bool DoesNotReturn =
false;
4595 bool IsReturnValueUsed =
false;
4596 EVT VT =
Op.getValueType();
4606 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4618 if (ExtraAlignSpace) {
4630SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4632 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4635 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4644 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4647 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4648 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4659 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4660 MachinePointerInfo());
4663 if (ExtraAlignSpace)
4670 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4671 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4687 if (RequiredAlign > StackAlign) {
4697 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4698 MachinePointerInfo());
4704SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4708 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4713 unsigned Opcode)
const {
4714 EVT VT =
Op.getValueType();
4720 assert(Subtarget.hasMiscellaneousExtensions2());
4725 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4731 EVT VT =
Op.getValueType();
4739 else if (Subtarget.hasMiscellaneousExtensions2())
4744 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4779 EVT VT =
Op.getValueType();
4792 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4800 EVT VT =
Op.getValueType();
4820 EVT VT =
Op.getValueType();
4827 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4832 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4841 uint64_t Masks[] = {
Known[0].Zero.getZExtValue(),
4842 Known[1].Zero.getZExtValue() };
4844 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4846 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4883 MVT::i64, HighOp, Low32);
4889 SDNode *
N =
Op.getNode();
4894 if (
N->getValueType(0) == MVT::i128) {
4895 unsigned BaseOp = 0;
4896 unsigned FlagOp = 0;
4897 bool IsBorrow =
false;
4898 switch (
Op.getOpcode()) {
4902 FlagOp = SystemZISD::VACC;
4906 FlagOp = SystemZISD::VSCBI;
4921 unsigned BaseOp = 0;
4922 unsigned CCValid = 0;
4923 unsigned CCMask = 0;
4925 switch (
Op.getOpcode()) {
4928 BaseOp = SystemZISD::SADDO;
4933 BaseOp = SystemZISD::SSUBO;
4938 BaseOp = SystemZISD::UADDO;
4943 BaseOp = SystemZISD::USUBO;
4949 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4953 if (
N->getValueType(1) == MVT::i1)
4979 SDNode *
N =
Op.getNode();
4980 MVT VT =
N->getSimpleValueType(0);
4991 if (VT == MVT::i128) {
4992 unsigned BaseOp = 0;
4993 unsigned FlagOp = 0;
4994 bool IsBorrow =
false;
4995 switch (
Op.getOpcode()) {
4998 BaseOp = SystemZISD::VAC;
4999 FlagOp = SystemZISD::VACCC;
5002 BaseOp = SystemZISD::VSBI;
5003 FlagOp = SystemZISD::VSBCBI;
5022 unsigned BaseOp = 0;
5023 unsigned CCValid = 0;
5024 unsigned CCMask = 0;
5026 switch (
Op.getOpcode()) {
5032 BaseOp = SystemZISD::ADDCARRY;
5040 BaseOp = SystemZISD::SUBCARRY;
5051 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5055 if (
N->getValueType(1) == MVT::i1)
5063 EVT VT =
Op.getValueType();
5065 Op =
Op.getOperand(0);
5088 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5100 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5113 if (NumSignificantBits == 0)
5119 BitSize = std::min(BitSize, OrigBitSize);
5128 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5130 if (BitSize != OrigBitSize)
5167 EVT RegVT =
Op.getValueType();
5169 return lowerATOMIC_LDST_I128(
Op, DAG);
5170 return lowerLoadF16(
Op, DAG);
5176 if (
Node->getMemoryVT().getSizeInBits() == 128)
5177 return lowerATOMIC_LDST_I128(
Op, DAG);
5178 return lowerStoreF16(
Op, DAG);
5185 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5186 "Only custom lowering i128 or f128.");
5199 EVT WideVT = MVT::i32;
5222 unsigned Opcode)
const {
5226 EVT NarrowVT =
Node->getMemoryVT();
5227 EVT WideVT = MVT::i32;
5228 if (NarrowVT == WideVT)
5235 MachineMemOperand *MMO =
Node->getMemOperand();
5239 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5241 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5246 SDValue AlignedAddr, BitShift, NegBitShift;
5254 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5257 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5258 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5263 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5264 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5284 EVT MemVT =
Node->getMemoryVT();
5285 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5287 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5288 assert(Subtarget.hasInterlockedAccess1() &&
5289 "Should have been expanded by AtomicExpand pass.");
5295 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5296 Node->getMemOperand());
5299 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5310 MachineMemOperand *MMO =
Node->getMemOperand();
5313 if (
Node->getMemoryVT() == MVT::i128) {
5322 EVT NarrowVT =
Node->getMemoryVT();
5323 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5324 if (NarrowVT == WideVT) {
5325 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5326 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5328 DL, Tys,
Ops, NarrowVT, MMO);
5342 SDValue AlignedAddr, BitShift, NegBitShift;
5346 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5347 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5350 VTList,
Ops, NarrowVT, MMO);
5364SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5387 auto *Regs = Subtarget.getSpecialRegisters();
5390 "in GHC calling convention");
5392 Regs->getStackPointerRegister(),
Op.getValueType());
5398 auto *Regs = Subtarget.getSpecialRegisters();
5399 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5403 "in GHC calling convention");
5410 if (StoreBackchain) {
5412 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5413 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5414 MachinePointerInfo());
5417 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5420 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5421 MachinePointerInfo());
5428 bool IsData =
Op.getConstantOperandVal(4);
5431 return Op.getOperand(0);
5434 bool IsWrite =
Op.getConstantOperandVal(2);
5441 Node->getMemoryVT(),
Node->getMemOperand());
5445SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5447 unsigned Opcode, CCValid;
5449 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5460SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5462 unsigned Opcode, CCValid;
5465 if (
Op->getNumValues() == 1)
5467 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5472 unsigned Id =
Op.getConstantOperandVal(0);
5474 case Intrinsic::thread_pointer:
5475 return lowerThreadPointer(SDLoc(
Op), DAG);
5477 case Intrinsic::s390_vpdi:
5478 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5479 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5481 case Intrinsic::s390_vperm:
5482 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5483 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5485 case Intrinsic::s390_vuphb:
5486 case Intrinsic::s390_vuphh:
5487 case Intrinsic::s390_vuphf:
5488 case Intrinsic::s390_vuphg:
5489 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5492 case Intrinsic::s390_vuplhb:
5493 case Intrinsic::s390_vuplhh:
5494 case Intrinsic::s390_vuplhf:
5495 case Intrinsic::s390_vuplhg:
5496 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5499 case Intrinsic::s390_vuplb:
5500 case Intrinsic::s390_vuplhw:
5501 case Intrinsic::s390_vuplf:
5502 case Intrinsic::s390_vuplg:
5503 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5506 case Intrinsic::s390_vupllb:
5507 case Intrinsic::s390_vupllh:
5508 case Intrinsic::s390_vupllf:
5509 case Intrinsic::s390_vupllg:
5510 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5513 case Intrinsic::s390_vsumb:
5514 case Intrinsic::s390_vsumh:
5515 case Intrinsic::s390_vsumgh:
5516 case Intrinsic::s390_vsumgf:
5517 case Intrinsic::s390_vsumqf:
5518 case Intrinsic::s390_vsumqg:
5519 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5520 Op.getOperand(1),
Op.getOperand(2));
5522 case Intrinsic::s390_vaq:
5524 Op.getOperand(1),
Op.getOperand(2));
5525 case Intrinsic::s390_vaccb:
5526 case Intrinsic::s390_vacch:
5527 case Intrinsic::s390_vaccf:
5528 case Intrinsic::s390_vaccg:
5529 case Intrinsic::s390_vaccq:
5530 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5531 Op.getOperand(1),
Op.getOperand(2));
5532 case Intrinsic::s390_vacq:
5533 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5534 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5535 case Intrinsic::s390_vacccq:
5536 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5537 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5539 case Intrinsic::s390_vsq:
5541 Op.getOperand(1),
Op.getOperand(2));
5542 case Intrinsic::s390_vscbib:
5543 case Intrinsic::s390_vscbih:
5544 case Intrinsic::s390_vscbif:
5545 case Intrinsic::s390_vscbig:
5546 case Intrinsic::s390_vscbiq:
5547 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5548 Op.getOperand(1),
Op.getOperand(2));
5549 case Intrinsic::s390_vsbiq:
5550 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5551 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5552 case Intrinsic::s390_vsbcbiq:
5553 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5554 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5556 case Intrinsic::s390_vmhb:
5557 case Intrinsic::s390_vmhh:
5558 case Intrinsic::s390_vmhf:
5559 case Intrinsic::s390_vmhg:
5560 case Intrinsic::s390_vmhq:
5562 Op.getOperand(1),
Op.getOperand(2));
5563 case Intrinsic::s390_vmlhb:
5564 case Intrinsic::s390_vmlhh:
5565 case Intrinsic::s390_vmlhf:
5566 case Intrinsic::s390_vmlhg:
5567 case Intrinsic::s390_vmlhq:
5569 Op.getOperand(1),
Op.getOperand(2));
5571 case Intrinsic::s390_vmahb:
5572 case Intrinsic::s390_vmahh:
5573 case Intrinsic::s390_vmahf:
5574 case Intrinsic::s390_vmahg:
5575 case Intrinsic::s390_vmahq:
5576 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5577 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5578 case Intrinsic::s390_vmalhb:
5579 case Intrinsic::s390_vmalhh:
5580 case Intrinsic::s390_vmalhf:
5581 case Intrinsic::s390_vmalhg:
5582 case Intrinsic::s390_vmalhq:
5583 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5584 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5586 case Intrinsic::s390_vmeb:
5587 case Intrinsic::s390_vmeh:
5588 case Intrinsic::s390_vmef:
5589 case Intrinsic::s390_vmeg:
5590 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5591 Op.getOperand(1),
Op.getOperand(2));
5592 case Intrinsic::s390_vmleb:
5593 case Intrinsic::s390_vmleh:
5594 case Intrinsic::s390_vmlef:
5595 case Intrinsic::s390_vmleg:
5596 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5597 Op.getOperand(1),
Op.getOperand(2));
5598 case Intrinsic::s390_vmob:
5599 case Intrinsic::s390_vmoh:
5600 case Intrinsic::s390_vmof:
5601 case Intrinsic::s390_vmog:
5602 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5603 Op.getOperand(1),
Op.getOperand(2));
5604 case Intrinsic::s390_vmlob:
5605 case Intrinsic::s390_vmloh:
5606 case Intrinsic::s390_vmlof:
5607 case Intrinsic::s390_vmlog:
5608 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5609 Op.getOperand(1),
Op.getOperand(2));
5611 case Intrinsic::s390_vmaeb:
5612 case Intrinsic::s390_vmaeh:
5613 case Intrinsic::s390_vmaef:
5614 case Intrinsic::s390_vmaeg:
5616 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5617 Op.getOperand(1),
Op.getOperand(2)),
5619 case Intrinsic::s390_vmaleb:
5620 case Intrinsic::s390_vmaleh:
5621 case Intrinsic::s390_vmalef:
5622 case Intrinsic::s390_vmaleg:
5624 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5625 Op.getOperand(1),
Op.getOperand(2)),
5627 case Intrinsic::s390_vmaob:
5628 case Intrinsic::s390_vmaoh:
5629 case Intrinsic::s390_vmaof:
5630 case Intrinsic::s390_vmaog:
5632 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5633 Op.getOperand(1),
Op.getOperand(2)),
5635 case Intrinsic::s390_vmalob:
5636 case Intrinsic::s390_vmaloh:
5637 case Intrinsic::s390_vmalof:
5638 case Intrinsic::s390_vmalog:
5640 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5641 Op.getOperand(1),
Op.getOperand(2)),
5662 { SystemZISD::MERGE_HIGH, 8,
5663 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5665 { SystemZISD::MERGE_HIGH, 4,
5666 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5668 { SystemZISD::MERGE_HIGH, 2,
5669 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5671 { SystemZISD::MERGE_HIGH, 1,
5672 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5674 { SystemZISD::MERGE_LOW, 8,
5675 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5677 { SystemZISD::MERGE_LOW, 4,
5678 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5680 { SystemZISD::MERGE_LOW, 2,
5681 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5683 { SystemZISD::MERGE_LOW, 1,
5684 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5686 { SystemZISD::PACK, 4,
5687 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5689 { SystemZISD::PACK, 2,
5690 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5692 { SystemZISD::PACK, 1,
5693 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5695 { SystemZISD::PERMUTE_DWORDS, 4,
5696 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5698 { SystemZISD::PERMUTE_DWORDS, 1,
5699 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5713 OpNo0 = OpNo1 = OpNos[1];
5714 }
else if (OpNos[1] < 0) {
5715 OpNo0 = OpNo1 = OpNos[0];
5733 unsigned &OpNo0,
unsigned &OpNo1) {
5734 int OpNos[] = { -1, -1 };
5747 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5749 OpNos[ModelOpNo] = RealOpNo;
5757 unsigned &OpNo0,
unsigned &OpNo1) {
5774 int Elt = Bytes[From];
5777 Transform[From] = -1;
5779 while (
P.Bytes[To] != Elt) {
5784 Transform[From] = To;
5808 Bytes.
resize(NumElements * BytesPerElement, -1);
5809 for (
unsigned I = 0;
I < NumElements; ++
I) {
5810 int Index = VSN->getMaskElt(
I);
5812 for (
unsigned J = 0; J < BytesPerElement; ++J)
5813 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5817 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5820 Bytes.
resize(NumElements * BytesPerElement, -1);
5821 for (
unsigned I = 0;
I < NumElements; ++
I)
5822 for (
unsigned J = 0; J < BytesPerElement; ++J)
5823 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5834 unsigned BytesPerElement,
int &
Base) {
5836 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5837 if (Bytes[Start +
I] >= 0) {
5838 unsigned Elem = Bytes[Start +
I];
5842 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5844 }
else if (
unsigned(
Base) != Elem -
I)
5857 unsigned &StartIndex,
unsigned &OpNo0,
5859 int OpNos[] = { -1, -1 };
5861 for (
unsigned I = 0;
I < 16; ++
I) {
5862 int Index = Bytes[
I];
5868 Shift = ExpectedShift;
5869 else if (Shift != ExpectedShift)
5873 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5875 OpNos[ModelOpNo] = RealOpNo;
5888 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5889 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5897 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5899 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5900 }
else if (
P.Opcode == SystemZISD::PACK) {
5903 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5912 N =
N->getOperand(0);
5915 return Op->getZExtValue() == 0;
5921 for (
unsigned I = 0;
I < Num ;
I++)
5933 for (
unsigned I = 0;
I < 2; ++
I)
5937 unsigned StartIndex, OpNo0, OpNo1;
5939 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5946 if (ZeroVecIdx != UINT32_MAX) {
5947 bool MaskFirst =
true;
5952 if (OpNo == ZeroVecIdx &&
I == 0) {
5957 if (OpNo != ZeroVecIdx && Byte == 0) {
5964 if (ZeroIdx != -1) {
5967 if (Bytes[
I] >= 0) {
5970 if (OpNo == ZeroVecIdx)
5982 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5985 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5997 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
6003struct GeneralShuffle {
6004 GeneralShuffle(EVT vt)
6005 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
6009 void tryPrepareForUnpack();
6010 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6025 unsigned UnpackFromEltSize;
6032void GeneralShuffle::addUndef() {
6034 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6035 Bytes.push_back(-1);
6044bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6050 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6055 if (FromBytesPerElement < BytesPerElement)
6059 (FromBytesPerElement - BytesPerElement));
6062 while (
Op.getNode()) {
6064 Op =
Op.getOperand(0);
6080 }
else if (
Op.isUndef()) {
6089 for (; OpNo <
Ops.size(); ++OpNo)
6090 if (
Ops[OpNo] ==
Op)
6092 if (OpNo ==
Ops.size())
6097 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6098 Bytes.push_back(
Base +
I);
6107 if (
Ops.size() == 0)
6111 tryPrepareForUnpack();
6114 if (
Ops.size() == 1)
6126 unsigned Stride = 1;
6127 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6128 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6138 else if (OpNo ==
I + Stride)
6149 if (NewBytes[J] >= 0) {
6151 "Invalid double permute");
6154 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6160 if (NewBytes[J] >= 0)
6176 unsigned OpNo0, OpNo1;
6180 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6185 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6192 dbgs() <<
Msg.c_str() <<
" { ";
6193 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6194 dbgs() << Bytes[
I] <<
" ";
6202void GeneralShuffle::tryPrepareForUnpack() {
6204 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6209 if (
Ops.size() > 2 &&
6214 UnpackFromEltSize = 1;
6215 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6216 bool MatchUnpack =
true;
6219 unsigned ToEltSize = UnpackFromEltSize * 2;
6220 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6223 if (Bytes[Elt] != -1) {
6225 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6226 MatchUnpack =
false;
6232 if (
Ops.size() == 2) {
6234 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6236 if (SrcBytes[i] == -1)
6238 if (SrcBytes[i] % 16 !=
int(i))
6239 CanUseUnpackHigh =
false;
6241 CanUseUnpackLow =
false;
6242 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6243 UnpackFromEltSize = UINT_MAX;
6247 if (!CanUseUnpackHigh)
6253 if (UnpackFromEltSize > 4)
6256 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6257 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6259 dumpBytes(Bytes,
"Original Bytes vector:"););
6268 Elt += UnpackFromEltSize;
6269 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6270 Bytes[
B] = Bytes[Elt];
6278 Ops.erase(&
Ops[ZeroVecOpNo]);
6280 if (Bytes[
I] >= 0) {
6282 if (OpNo > ZeroVecOpNo)
6293 if (!unpackWasPrepared())
6295 unsigned InBits = UnpackFromEltSize * 8;
6299 unsigned OutBits = InBits * 2;
6302 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6303 : SystemZISD::UNPACKL_HIGH,
6304 DL, OutVT, PackedOp);
6309 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6310 if (!
Op.getOperand(
I).isUndef())
6326 if (
Value.isUndef())
6338 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6341 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6342 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6363 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6379 GeneralShuffle GS(VT);
6381 bool FoundOne =
false;
6382 for (
unsigned I = 0;
I < NumElements; ++
I) {
6385 Op =
Op.getOperand(0);
6388 unsigned Elem =
Op.getConstantOperandVal(1);
6389 if (!GS.add(
Op.getOperand(0), Elem))
6392 }
else if (
Op.isUndef()) {
6406 if (!ResidueOps.
empty()) {
6407 while (ResidueOps.
size() < NumElements)
6409 for (
auto &
Op : GS.Ops) {
6410 if (!
Op.getNode()) {
6416 return GS.getNode(DAG,
SDLoc(BVN));
6419bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6425 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6436 "Handling full vectors only.");
6456 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6468 unsigned int NumElements = Elems.
size();
6469 unsigned int Count = 0;
6470 for (
auto Elem : Elems) {
6471 if (!Elem.isUndef()) {
6474 else if (Elem != Single) {
6494 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6495 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6498 bool AllLoads =
true;
6499 for (
auto Elem : Elems)
6500 if (!isVectorElementLoad(Elem)) {
6506 if (VT == MVT::v2i64 && !AllLoads)
6510 if (VT == MVT::v2f64 && !AllLoads)
6520 if (VT == MVT::v4f32 && !AllLoads)
6524 if (VT == MVT::v8f16 && !AllLoads) {
6533 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6542 unsigned NumConstants = 0;
6543 for (
unsigned I = 0;
I < NumElements; ++
I) {
6557 if (NumConstants > 0) {
6558 for (
unsigned I = 0;
I < NumElements; ++
I)
6569 std::map<const SDNode*, unsigned> UseCounts;
6570 SDNode *LoadMaxUses =
nullptr;
6571 for (
unsigned I = 0;
I < NumElements; ++
I)
6572 if (isVectorElementLoad(Elems[
I])) {
6573 SDNode *Ld = Elems[
I].getNode();
6574 unsigned Count = ++UseCounts[Ld];
6575 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6578 if (LoadMaxUses !=
nullptr) {
6579 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6583 unsigned I1 = NumElements / 2 - 1;
6584 unsigned I2 = NumElements - 1;
6585 bool Def1 = !Elems[
I1].isUndef();
6586 bool Def2 = !Elems[I2].isUndef();
6600 for (
unsigned I = 0;
I < NumElements; ++
I)
6601 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6611 EVT VT =
Op.getValueType();
6613 if (BVN->isConstant()) {
6614 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6632 for (
unsigned I = 0;
I < NumElements; ++
I)
6634 return buildVector(DAG,
DL, VT,
Ops);
6641 EVT VT =
Op.getValueType();
6644 if (VSN->isSplat()) {
6646 unsigned Index = VSN->getSplatIndex();
6648 "Splat index should be defined and in first operand");
6654 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6658 GeneralShuffle
GS(VT);
6659 for (
unsigned I = 0;
I < NumElements; ++
I) {
6660 int Elt = VSN->getMaskElt(
I);
6663 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6664 unsigned(Elt) % NumElements))
6667 return GS.getNode(DAG, SDLoc(VSN));
6682 assert(
Op.getSimpleValueType() == MVT::i64 &&
6683 "Expexted to convert i64 to f16.");
6695 assert(
Op.getSimpleValueType() == MVT::f16 &&
6696 "Expected to convert f16 to i64.");
6713 EVT VT =
Op.getValueType();
6718 if (VT == MVT::v2f64 &&
6742SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6748 EVT VT =
Op.getValueType();
6753 uint64_t
Index = CIndexN->getZExtValue();
6762 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6770SDValue SystemZTargetLowering::
6773 EVT OutVT =
Op.getValueType();
6777 unsigned StartOffset = 0;
6784 ArrayRef<int> ShuffleMask = SVN->
getMask();
6789 if (ToBits == 64 && OutNumElts == 2) {
6790 int NumElem = ToBits / FromBits;
6791 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6797 int StartOffsetCandidate = -1;
6798 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6799 if (ShuffleMask[Elt] == -1)
6801 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6802 if (StartOffsetCandidate == -1)
6803 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6804 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6807 StartOffsetCandidate = -1;
6810 if (StartOffsetCandidate != -1) {
6811 StartOffset = StartOffsetCandidate;
6820 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6821 if (StartOffset >= OutNumElts) {
6822 Opcode = SystemZISD::UNPACK_LOW;
6823 StartOffset -= OutNumElts;
6825 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6826 }
while (FromBits != ToBits);
6831SDValue SystemZTargetLowering::
6835 EVT OutVT =
Op.getValueType();
6839 unsigned NumInPerOut = InNumElts / OutNumElts;
6844 SmallVector<int, 16>
Mask(InNumElts);
6845 unsigned ZeroVecElt = InNumElts;
6846 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6847 unsigned MaskElt = PackedElt * NumInPerOut;
6848 unsigned End = MaskElt + NumInPerOut - 1;
6849 for (; MaskElt < End; MaskElt++)
6850 Mask[MaskElt] = ZeroVecElt++;
6851 Mask[MaskElt] = PackedElt;
6858 unsigned ByScalar)
const {
6863 EVT VT =
Op.getValueType();
6868 APInt SplatBits, SplatUndef;
6869 unsigned SplatBitSize;
6873 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6874 ElemBitSize,
true) &&
6875 SplatBitSize == ElemBitSize) {
6878 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6881 BitVector UndefElements;
6887 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6894 if (VSN->isSplat()) {
6895 SDValue VSNOp0 = VSN->getOperand(0);
6896 unsigned Index = VSN->getSplatIndex();
6898 "Splat index should be defined and in first operand");
6905 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6923 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6924 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6927 if (ShiftAmt > 120) {
6931 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6935 SmallVector<int, 16>
Mask(16);
6936 for (
unsigned Elt = 0; Elt < 16; Elt++)
6937 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6939 if ((ShiftAmt & 7) == 0)
6943 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6961 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6962 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6965 if (ShiftAmt > 120) {
6969 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6973 SmallVector<int, 16>
Mask(16);
6974 for (
unsigned Elt = 0; Elt < 16; Elt++)
6975 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6977 if ((ShiftAmt & 7) == 0)
6981 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6993 MVT DstVT =
Op.getSimpleValueType();
6996 unsigned SrcAS =
N->getSrcAddressSpace();
6998 assert(SrcAS !=
N->getDestAddressSpace() &&
6999 "addrspacecast must be between different address spaces");
7007 }
else if (DstVT == MVT::i32) {
7021 if (
In.getSimpleValueType() != MVT::f16)
7028 SDValue Chain,
bool IsStrict)
const {
7029 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7032 std::tie(Result, Chain) =
7041 bool IsStrict =
Op->isStrictFPOpcode();
7043 MVT VT =
Op.getSimpleValueType();
7044 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7052 if (!Subtarget.hasFPExtension() && !IsSigned)
7063 if (VT == MVT::i128) {
7066 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7076 bool IsStrict =
Op->isStrictFPOpcode();
7078 MVT VT =
Op.getSimpleValueType();
7079 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7084 if (VT == MVT::f16) {
7091 if (!Subtarget.hasFPExtension() && !IsSigned)
7094 if (InVT == MVT::i128) {
7097 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7106 EVT RegVT =
Op.getValueType();
7107 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7114 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7116 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7117 AtomicLd->getMemOperand());
7137 Shft, AtomicSt->getBasePtr(),
7138 AtomicSt->getMemOperand());
7148 MVT ResultVT =
Op.getSimpleValueType();
7150 unsigned Check =
Op.getConstantOperandVal(1);
7152 unsigned TDCMask = 0;
7187 MachinePointerInfo MPI =
7193 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7197 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7202 switch (
Op.getOpcode()) {
7204 return lowerFRAMEADDR(
Op, DAG);
7206 return lowerRETURNADDR(
Op, DAG);
7208 return lowerBR_CC(
Op, DAG);
7210 return lowerSELECT_CC(
Op, DAG);
7212 return lowerSETCC(
Op, DAG);
7214 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7216 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7228 return lowerBITCAST(
Op, DAG);
7230 return lowerVASTART(
Op, DAG);
7232 return lowerVACOPY(
Op, DAG);
7234 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7236 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7238 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7240 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7242 return lowerSMUL_LOHI(
Op, DAG);
7244 return lowerUMUL_LOHI(
Op, DAG);
7246 return lowerSDIVREM(
Op, DAG);
7248 return lowerUDIVREM(
Op, DAG);
7253 return lowerXALUO(
Op, DAG);
7256 return lowerUADDSUBO_CARRY(
Op, DAG);
7258 return lowerOR(
Op, DAG);
7260 return lowerCTPOP(
Op, DAG);
7262 return lowerVECREDUCE_ADD(
Op, DAG);
7264 return lowerATOMIC_FENCE(
Op, DAG);
7266 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7268 return lowerATOMIC_STORE(
Op, DAG);
7270 return lowerATOMIC_LOAD(
Op, DAG);
7272 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7274 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7276 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7278 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7280 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7282 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7284 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7286 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7288 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7290 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7292 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7294 return lowerSTACKSAVE(
Op, DAG);
7296 return lowerSTACKRESTORE(
Op, DAG);
7298 return lowerPREFETCH(
Op, DAG);
7300 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7302 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7304 return lowerBUILD_VECTOR(
Op, DAG);
7306 return lowerVECTOR_SHUFFLE(
Op, DAG);
7308 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7310 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7312 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7314 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7316 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7318 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7320 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7322 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7326 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7328 return lowerFSHL(
Op, DAG);
7330 return lowerFSHR(
Op, DAG);
7333 return lowerFP_EXTEND(
Op, DAG);
7338 return lower_FP_TO_INT(
Op, DAG);
7343 return lower_INT_TO_FP(
Op, DAG);
7345 return lowerLoadF16(
Op, DAG);
7347 return lowerStoreF16(
Op, DAG);
7349 return lowerIS_FPCLASS(
Op, DAG);
7351 return lowerGET_ROUNDING(
Op, DAG);
7353 return lowerREADCYCLECOUNTER(
Op, DAG);
7375 &SystemZ::FP128BitRegClass);
7384 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7399 &SystemZ::FP128BitRegClass);
7416 switch (
N->getOpcode()) {
7420 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7423 DL, Tys,
Ops, MVT::i128, MMO);
7426 if (
N->getValueType(0) == MVT::f128)
7440 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7443 DL, Tys,
Ops, MVT::i128, MMO);
7449 MVT::Other, Res), 0);
7461 DL, Tys,
Ops, MVT::i128, MMO);
7475 EVT SrcVT = Src.getValueType();
7476 EVT ResVT =
N->getValueType(0);
7477 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7479 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7480 if (Subtarget.hasVector()) {
7488 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7490 Subtarget.hasVector()
7504 bool IsStrict =
N->isStrictFPOpcode();
7506 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7507 EVT ResVT =
N->getValueType(0);
7509 if (ResVT == MVT::f16) {
7532 bool IsStrict =
N->isStrictFPOpcode();
7534 EVT ResVT =
N->getValueType(0);
7535 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7538 if (InVT == MVT::f16) {
7544 std::tie(InF32, Chain) =
7569bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7570 if (!Subtarget.hasVector())
7584 DAGCombinerInfo &DCI,
7592 unsigned Opcode =
Op.getOpcode();
7595 Op =
Op.getOperand(0);
7597 canTreatAsByteVector(
Op.getValueType())) {
7606 BytesPerElement,
First))
7613 if (Byte % BytesPerElement != 0)
7616 Index = Byte / BytesPerElement;
7620 canTreatAsByteVector(
Op.getValueType())) {
7623 EVT OpVT =
Op.getValueType();
7625 if (OpBytesPerElement < BytesPerElement)
7629 unsigned End = (
Index + 1) * BytesPerElement;
7630 if (End % OpBytesPerElement != 0)
7633 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7634 if (!
Op.getValueType().isInteger()) {
7637 DCI.AddToWorklist(
Op.getNode());
7642 DCI.AddToWorklist(
Op.getNode());
7649 canTreatAsByteVector(
Op.getValueType()) &&
7650 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7652 EVT ExtVT =
Op.getValueType();
7653 EVT OpVT =
Op.getOperand(0).getValueType();
7656 unsigned Byte =
Index * BytesPerElement;
7657 unsigned SubByte =
Byte % ExtBytesPerElement;
7658 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7659 if (SubByte < MinSubByte ||
7660 SubByte + BytesPerElement > ExtBytesPerElement)
7663 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7665 Byte += SubByte - MinSubByte;
7666 if (Byte % BytesPerElement != 0)
7668 Op =
Op.getOperand(0);
7675 if (
Op.getValueType() != VecVT) {
7677 DCI.AddToWorklist(
Op.getNode());
7687SDValue SystemZTargetLowering::combineTruncateExtract(
7696 if (canTreatAsByteVector(VecVT)) {
7700 if (BytesPerElement % TruncBytes == 0) {
7706 unsigned Scale = BytesPerElement / TruncBytes;
7707 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7714 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7715 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7723SDValue SystemZTargetLowering::combineZERO_EXTEND(
7724 SDNode *
N, DAGCombinerInfo &DCI)
const {
7726 SelectionDAG &DAG = DCI.DAG;
7728 EVT VT =
N->getValueType(0);
7729 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7732 if (TrueOp && FalseOp) {
7742 DCI.CombineTo(N0.
getNode(), TruncSelect);
7785 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7803SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7804 SDNode *
N, DAGCombinerInfo &DCI)
const {
7808 SelectionDAG &DAG = DCI.DAG;
7810 EVT VT =
N->getValueType(0);
7824SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7825 SDNode *
N, DAGCombinerInfo &DCI)
const {
7829 SelectionDAG &DAG = DCI.DAG;
7831 EVT VT =
N->getValueType(0);
7838 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7839 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7855SDValue SystemZTargetLowering::combineMERGE(
7856 SDNode *
N, DAGCombinerInfo &DCI)
const {
7857 SelectionDAG &DAG = DCI.DAG;
7858 unsigned Opcode =
N->getOpcode();
7866 if (Op1 ==
N->getOperand(0))
7871 if (ElemBytes <= 4) {
7872 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7873 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7879 DCI.AddToWorklist(Op1.
getNode());
7882 DCI.AddToWorklist(
Op.getNode());
7891 LoPart = HiPart =
nullptr;
7896 if (
Use.getResNo() != 0)
7901 bool IsLoPart =
true;
7926 LoPart = HiPart =
nullptr;
7931 if (
Use.getResNo() != 0)
7937 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7940 switch (
User->getConstantOperandVal(1)) {
7941 case SystemZ::subreg_l64:
7946 case SystemZ::subreg_h64:
7958SDValue SystemZTargetLowering::combineLOAD(
7959 SDNode *
N, DAGCombinerInfo &DCI)
const {
7960 SelectionDAG &DAG = DCI.DAG;
7961 EVT LdVT =
N->getValueType(0);
7965 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7966 if (PtrVT != LoadNodeVT) {
7970 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7971 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7972 LN->getMemOperand());
7982 SDNode *LoPart, *HiPart;
7990 LD->getPointerInfo(),
LD->getBaseAlign(),
7991 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7993 DCI.CombineTo(HiPart, EltLoad,
true);
8000 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
8001 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8003 DCI.CombineTo(LoPart, EltLoad,
true);
8010 DCI.AddToWorklist(Chain.
getNode());
8025 for (SDUse &Use :
N->uses()) {
8026 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8030 }
else if (
Use.getResNo() == 0)
8033 if (!Replicate || OtherUses.
empty())
8039 for (SDNode *U : OtherUses) {
8042 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8048bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8049 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8051 if (Subtarget.hasVectorEnhancements2())
8052 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8064 for (
unsigned i = 0; i < NumElts; ++i) {
8065 if (M[i] < 0)
continue;
8066 if ((
unsigned) M[i] != NumElts - 1 - i)
8074 for (
auto *U : StoredVal->
users()) {
8076 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8135SDValue SystemZTargetLowering::combineSTORE(
8136 SDNode *
N, DAGCombinerInfo &DCI)
const {
8137 SelectionDAG &DAG = DCI.DAG;
8140 EVT MemVT = SN->getMemoryVT();
8144 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8145 if (PtrVT != StoreNodeVT) {
8149 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8150 SN->getPointerInfo(), SN->getBaseAlign(),
8151 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8159 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8161 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8162 DCI.AddToWorklist(
Value.getNode());
8166 SN->getBasePtr(), SN->getMemoryVT(),
8167 SN->getMemOperand());
8178 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8182 if (!SN->isTruncatingStore() &&
8198 Ops, MemVT, SN->getMemOperand());
8201 if (!SN->isTruncatingStore() &&
8204 Subtarget.hasVectorEnhancements2()) {
8206 ArrayRef<int> ShuffleMask = SVN->
getMask();
8214 Ops, MemVT, SN->getMemOperand());
8219 if (!SN->isTruncatingStore() &&
8222 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8226 Ops, MemVT, SN->getMemOperand());
8236 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8237 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8239 SN->getChain(),
DL, LoPart,
8241 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8242 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8260 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8262 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8266 APInt Val =
C->getAPIntValue();
8269 assert(SN->isTruncatingStore() &&
8270 "Non-truncating store and immediate value does not fit?");
8271 Val = Val.
trunc(TotBytes * 8);
8274 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8275 if (VCI.isVectorConstantLegal(Subtarget) &&
8276 VCI.Opcode == SystemZISD::REPLICATE) {
8284 auto FindReplicatedReg = [&](
SDValue MulOp) {
8285 EVT MulVT = MulOp.getValueType();
8286 if (MulOp->getOpcode() ==
ISD::MUL &&
8287 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8291 WordVT =
LHS->getOperand(0).getValueType();
8298 SystemZVectorConstantInfo VCI(
8300 if (VCI.isVectorConstantLegal(Subtarget) &&
8301 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8302 WordVT == VCI.VecVT.getScalarType())
8314 FindReplicatedReg(SplatVal);
8319 FindReplicatedReg(Op1);
8324 "Bad type handling");
8328 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8329 SN->getBasePtr(), SN->getMemOperand());
8336SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8337 SDNode *
N, DAGCombinerInfo &DCI)
const {
8338 SelectionDAG &DAG = DCI.DAG;
8341 N->getOperand(0).hasOneUse() &&
8342 Subtarget.hasVectorEnhancements2()) {
8344 ArrayRef<int> ShuffleMask = SVN->
getMask();
8357 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8361 DCI.CombineTo(
N, ESLoad);
8365 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8375SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8376 SDNode *
N, DAGCombinerInfo &DCI)
const {
8377 SelectionDAG &DAG = DCI.DAG;
8379 if (!Subtarget.hasVector())
8385 Op.getValueType().isVector() &&
8386 Op.getOperand(0).getValueType().isVector() &&
8387 Op.getValueType().getVectorNumElements() ==
8388 Op.getOperand(0).getValueType().getVectorNumElements())
8389 Op =
Op.getOperand(0);
8393 EVT VecVT =
Op.getValueType();
8396 Op.getOperand(0),
N->getOperand(1));
8397 DCI.AddToWorklist(
Op.getNode());
8399 if (EltVT !=
N->getValueType(0)) {
8400 DCI.AddToWorklist(
Op.getNode());
8410 if (canTreatAsByteVector(VecVT))
8411 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8412 IndexN->getZExtValue(), DCI,
false);
8417SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8418 SDNode *
N, DAGCombinerInfo &DCI)
const {
8419 SelectionDAG &DAG = DCI.DAG;
8421 if (
N->getOperand(0) ==
N->getOperand(1))
8422 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8432 if (Chain1 == Chain2)
8440SDValue SystemZTargetLowering::combineFP_ROUND(
8441 SDNode *
N, DAGCombinerInfo &DCI)
const {
8443 if (!Subtarget.hasVector())
8452 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8453 SelectionDAG &DAG = DCI.DAG;
8455 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8461 for (
auto *U : Vec->
users()) {
8462 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8464 U->getOperand(0) == Vec &&
8466 U->getConstantOperandVal(1) == 1) {
8468 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8472 if (
N->isStrictFPOpcode()) {
8476 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8477 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8480 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8482 DCI.AddToWorklist(VRound.
getNode());
8486 DCI.AddToWorklist(Extract1.
getNode());
8492 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8495 N->getVTList(), Extract0, Chain);
8504SDValue SystemZTargetLowering::combineFP_EXTEND(
8505 SDNode *
N, DAGCombinerInfo &DCI)
const {
8507 if (!Subtarget.hasVector())
8516 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8517 SelectionDAG &DAG = DCI.DAG;
8519 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8525 for (
auto *U : Vec->
users()) {
8526 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8528 U->getOperand(0) == Vec &&
8530 U->getConstantOperandVal(1) == 2) {
8532 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8536 if (
N->isStrictFPOpcode()) {
8540 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8541 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8544 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8546 DCI.AddToWorklist(VExtend.
getNode());
8550 DCI.AddToWorklist(Extract1.
getNode());
8556 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8559 N->getVTList(), Extract0, Chain);
8568SDValue SystemZTargetLowering::combineINT_TO_FP(
8569 SDNode *
N, DAGCombinerInfo &DCI)
const {
8572 SelectionDAG &DAG = DCI.DAG;
8574 unsigned Opcode =
N->getOpcode();
8575 EVT OutVT =
N->getValueType(0);
8579 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8585 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8586 OutScalarBits <= 64) {
8590 unsigned ExtOpcode =
8593 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8598SDValue SystemZTargetLowering::combineFCOPYSIGN(
8599 SDNode *
N, DAGCombinerInfo &DCI)
const {
8600 SelectionDAG &DAG = DCI.DAG;
8601 EVT VT =
N->getValueType(0);
8614SDValue SystemZTargetLowering::combineBSWAP(
8615 SDNode *
N, DAGCombinerInfo &DCI)
const {
8616 SelectionDAG &DAG = DCI.DAG;
8619 N->getOperand(0).hasOneUse() &&
8620 canLoadStoreByteSwapped(
N->getValueType(0))) {
8629 EVT LoadVT =
N->getValueType(0);
8630 if (LoadVT == MVT::i16)
8635 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8639 if (
N->getValueType(0) == MVT::i16)
8644 DCI.CombineTo(
N, ResVal);
8648 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8657 Op.getValueType().isVector() &&
8658 Op.getOperand(0).getValueType().isVector() &&
8659 Op.getValueType().getVectorNumElements() ==
8660 Op.getOperand(0).getValueType().getVectorNumElements())
8661 Op =
Op.getOperand(0);
8673 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8675 EVT VecVT =
N->getValueType(0);
8679 DCI.AddToWorklist(Vec.
getNode());
8683 DCI.AddToWorklist(Elt.
getNode());
8686 DCI.AddToWorklist(Vec.
getNode());
8688 DCI.AddToWorklist(Elt.
getNode());
8696 if (SV &&
Op.hasOneUse()) {
8704 EVT VecVT =
N->getValueType(0);
8707 DCI.AddToWorklist(Op0.
getNode());
8711 DCI.AddToWorklist(Op1.
getNode());
8714 DCI.AddToWorklist(Op0.
getNode());
8716 DCI.AddToWorklist(Op1.
getNode());
8724SDValue SystemZTargetLowering::combineSETCC(
8725 SDNode *
N, DAGCombinerInfo &DCI)
const {
8726 SelectionDAG &DAG = DCI.DAG;
8732 EVT VT =
N->getValueType(0);
8742 Src.getValueType().isFixedLengthVector() &&
8743 Src.getValueType().getScalarType() == MVT::i1) {
8744 EVT CmpVT = Src.getOperand(0).getValueType();
8761 unsigned Depth = 0) {
8769 case SystemZISD::IPM:
8774 case SystemZISD::SELECT_CCMASK: {
8776 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8777 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8780 return std::make_pair(OpCC, OpCCValid);
8785 int CCValidVal = CCValid->getZExtValue();
8786 return std::make_pair(Op4CCReg, CCValidVal);
8797 return std::make_pair(Op0CC, Op0CCValid);
8813 return {Val, Val, Val, Val};
8814 case SystemZISD::IPM: {
8819 for (
auto CC : {0, 1, 2, 3})
8822 return ShiftedCCVals;
8824 case SystemZISD::SELECT_CCMASK: {
8828 if (!CCValid || !CCMask)
8831 int CCValidVal = CCValid->getZExtValue();
8832 int CCMaskVal = CCMask->getZExtValue();
8842 if (TrueSDVals.empty() || FalseSDVals.empty())
8845 for (
auto &CCVal : {0, 1, 2, 3})
8846 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8848 : FalseSDVals[CCVal]);
8849 return MergedSDVals;
8866 if (Op0SDVals.empty() || Op1SDVals.empty())
8869 for (
auto CCVal : {0, 1, 2, 3})
8871 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8872 return BinaryOpSDVals;
8883 auto *CCNode = CCReg.
getNode();
8887 if (CCNode->getOpcode() == SystemZISD::TM) {
8890 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8893 if (!Op0Node || !Op1Node)
8895 auto Op0APVal = Op0Node->getAPIntValue();
8896 auto Op1APVal = Op1Node->getAPIntValue();
8897 auto Result = Op0APVal & Op1APVal;
8898 bool AllOnes = Result == Op1APVal;
8899 bool AllZeros = Result == 0;
8900 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8901 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8905 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8910 if (Op0SDVals.empty() || Op1SDVals.empty())
8913 for (
auto CC : {0, 1, 2, 3}) {
8914 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8918 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8920 NewCCMask &= Op0CCValid;
8923 CCValid = Op0CCValid;
8926 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8933 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8937 if (Op0SDVals.empty() || Op1SDVals.empty())
8941 auto CmpTypeVal = CmpType->getZExtValue();
8942 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8946 if (!Op0Node || !Op1Node)
8948 auto Op0APVal = Op0Node->getAPIntValue();
8949 auto Op1APVal = Op1Node->getAPIntValue();
8951 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8952 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8955 for (
auto CC : {0, 1, 2, 3}) {
8956 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8960 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8962 NewCCMask &= Op0CCValid;
8965 CCValid = Op0CCValid;
8978 const auto isFlagOutOpCC = [](
const Value *V) {
8980 const Value *RHSVal;
8987 if (CB->isInlineAsm()) {
8989 return IA && IA->getConstraintString().contains(
"{@cc}");
9000 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
9003 return {-1, -1, -1};
9007 DAGCombinerInfo &DCI)
const {
9013 if (!CCValid || !CCMask)
9016 int CCValidVal = CCValid->getZExtValue();
9017 int CCMaskVal = CCMask->getZExtValue();
9024 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9025 CCMaskVal != CCValidVal)
9026 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9030 N->getOperand(3), CCReg);
9034SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9035 SDNode *
N, DAGCombinerInfo &DCI)
const {
9041 if (!CCValid || !CCMask)
9044 int CCValidVal = CCValid->getZExtValue();
9045 int CCMaskVal = CCMask->getZExtValue();
9048 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9052 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9053 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9055 if (Val.getOperand(4) != CCReg)
9062 int CCMaskVal = CCMask->getZExtValue();
9063 for (
auto &CC : {0, 1, 2, 3})
9064 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9078 if (TrueSDVals.empty())
9079 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9080 if (FalseSDVals.empty())
9081 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9082 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9083 SmallSet<SDValue, 4> MergedSDValsSet;
9085 for (
auto CC : {0, 1, 2, 3}) {
9086 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9087 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9091 if (MergedSDValsSet.
size() == 1)
9092 return *MergedSDValsSet.
begin();
9093 if (MergedSDValsSet.
size() == 2) {
9094 auto BeginIt = MergedSDValsSet.
begin();
9095 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9096 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9099 for (
auto CC : {0, 1, 2, 3}) {
9101 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9102 ? (TrueSDVals[CC] == NewTrueVal)
9103 : (FalseSDVals[CC] == NewTrueVal);
9105 CCMaskVal = NewCCMask;
9106 CCMaskVal &= CCValidVal;
9109 IsCombinedCCReg =
true;
9117 if (CCMaskVal == CCValidVal)
9120 if (IsCombinedCCReg)
9122 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9129SDValue SystemZTargetLowering::combineGET_CCMASK(
9130 SDNode *
N, DAGCombinerInfo &DCI)
const {
9135 if (!CCValid || !CCMask)
9137 int CCValidVal = CCValid->getZExtValue();
9138 int CCMaskVal = CCMask->getZExtValue();
9143 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9148 if (!SelectCCValid || !SelectCCMask)
9150 int SelectCCValidVal = SelectCCValid->getZExtValue();
9151 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9155 if (!TrueVal || !FalseVal)
9159 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9160 SelectCCMaskVal ^= SelectCCValidVal;
9164 if (SelectCCValidVal & ~CCValidVal)
9166 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9169 return Select->getOperand(4);
9172SDValue SystemZTargetLowering::combineIntDIVREM(
9173 SDNode *
N, DAGCombinerInfo &DCI)
const {
9174 SelectionDAG &DAG = DCI.DAG;
9175 EVT VT =
N->getValueType(0);
9192SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9193 SDNode *
N, DAGCombinerInfo &DCI)
const {
9194 SelectionDAG &DAG = DCI.DAG;
9198 "SRL or SRA node is required here!");
9200 if (!Subtarget.hasVector())
9210 SDValue ShiftOperand =
N->getOperand(0);
9230 if (!IsSignExt && !IsZeroExt)
9238 unsigned ActiveBits = IsSignExt
9239 ?
Constant->getAPIntValue().getSignificantBits()
9240 :
Constant->getAPIntValue().getActiveBits();
9241 if (ActiveBits > NarrowVTSize)
9257 unsigned ActiveBits = IsSignExt
9258 ?
Constant->getAPIntValue().getSignificantBits()
9259 :
Constant->getAPIntValue().getActiveBits();
9260 if (ActiveBits > NarrowVTSize)
9277 "Cannot have a multiply node with two different operand types.");
9279 "Cannot have an add node with two different operand types.");
9290 if (ShiftAmt != NarrowVTSize)
9294 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9295 NarrowVT == MVT::v4i32 ||
9296 (Subtarget.hasVectorEnhancements3() &&
9297 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9303 MulhRightOp, MulhAddOp);
9304 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9315 EVT VT =
Op.getValueType();
9324 Op =
Op.getOperand(0);
9325 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9329 bool CanUseEven =
true, CanUseOdd =
true;
9330 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9331 if (ShuffleMask[Elt] == -1)
9333 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9335 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9338 Op =
Op.getOperand(0);
9340 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9342 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9348 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9352 Op =
Op.getOperand(0);
9354 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9356 unsigned Elem =
Op.getConstantOperandVal(1);
9357 Op =
Op.getOperand(0);
9359 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9361 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9368SDValue SystemZTargetLowering::combineMUL(
9369 SDNode *
N, DAGCombinerInfo &DCI)
const {
9370 SelectionDAG &DAG = DCI.DAG;
9377 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9378 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9383SDValue SystemZTargetLowering::combineINTRINSIC(
9384 SDNode *
N, DAGCombinerInfo &DCI)
const {
9385 SelectionDAG &DAG = DCI.DAG;
9387 unsigned Id =
N->getConstantOperandVal(1);
9391 case Intrinsic::s390_vll:
9392 case Intrinsic::s390_vlrl:
9394 if (
C->getZExtValue() >= 15)
9395 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9396 N->getOperand(3), MachinePointerInfo());
9399 case Intrinsic::s390_vstl:
9400 case Intrinsic::s390_vstrl:
9402 if (
C->getZExtValue() >= 15)
9403 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9404 N->getOperand(4), MachinePointerInfo());
9412 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9419 switch(
N->getOpcode()) {
9424 case SystemZISD::MERGE_HIGH:
9425 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9430 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9440 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9441 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9444 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9445 case ISD::MUL:
return combineMUL(
N, DCI);
9449 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9461 EVT VT =
Op.getValueType();
9464 unsigned Opcode =
Op.getOpcode();
9466 unsigned Id =
Op.getConstantOperandVal(0);
9468 case Intrinsic::s390_vpksh:
9469 case Intrinsic::s390_vpksf:
9470 case Intrinsic::s390_vpksg:
9471 case Intrinsic::s390_vpkshs:
9472 case Intrinsic::s390_vpksfs:
9473 case Intrinsic::s390_vpksgs:
9474 case Intrinsic::s390_vpklsh:
9475 case Intrinsic::s390_vpklsf:
9476 case Intrinsic::s390_vpklsg:
9477 case Intrinsic::s390_vpklshs:
9478 case Intrinsic::s390_vpklsfs:
9479 case Intrinsic::s390_vpklsgs:
9481 SrcDemE = DemandedElts;
9484 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9487 case Intrinsic::s390_vuphb:
9488 case Intrinsic::s390_vuphh:
9489 case Intrinsic::s390_vuphf:
9490 case Intrinsic::s390_vuplhb:
9491 case Intrinsic::s390_vuplhh:
9492 case Intrinsic::s390_vuplhf:
9493 SrcDemE =
APInt(NumElts * 2, 0);
9496 case Intrinsic::s390_vuplb:
9497 case Intrinsic::s390_vuplhw:
9498 case Intrinsic::s390_vuplf:
9499 case Intrinsic::s390_vupllb:
9500 case Intrinsic::s390_vupllh:
9501 case Intrinsic::s390_vupllf:
9502 SrcDemE =
APInt(NumElts * 2, 0);
9505 case Intrinsic::s390_vpdi: {
9507 SrcDemE =
APInt(NumElts, 0);
9508 if (!DemandedElts[OpNo - 1])
9510 unsigned Mask =
Op.getConstantOperandVal(3);
9511 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9513 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9516 case Intrinsic::s390_vsldb: {
9518 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9519 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9520 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9521 unsigned NumSrc0Els = 16 - FirstIdx;
9522 SrcDemE =
APInt(NumElts, 0);
9524 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9527 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9532 case Intrinsic::s390_vperm:
9541 case SystemZISD::JOIN_DWORDS:
9543 SrcDemE =
APInt(1, 1);
9545 case SystemZISD::SELECT_CCMASK:
9546 SrcDemE = DemandedElts;
9557 const APInt &DemandedElts,
9572 const APInt &DemandedElts,
9574 unsigned Depth)
const {
9578 unsigned Tmp0, Tmp1;
9580 Known.Zero.setBitsFrom(2);
9583 EVT VT =
Op.getValueType();
9584 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9587 "KnownBits does not match VT in bitwidth");
9590 "DemandedElts does not match VT number of elements");
9592 unsigned Opcode =
Op.getOpcode();
9594 bool IsLogical =
false;
9595 unsigned Id =
Op.getConstantOperandVal(0);
9597 case Intrinsic::s390_vpksh:
9598 case Intrinsic::s390_vpksf:
9599 case Intrinsic::s390_vpksg:
9600 case Intrinsic::s390_vpkshs:
9601 case Intrinsic::s390_vpksfs:
9602 case Intrinsic::s390_vpksgs:
9603 case Intrinsic::s390_vpklsh:
9604 case Intrinsic::s390_vpklsf:
9605 case Intrinsic::s390_vpklsg:
9606 case Intrinsic::s390_vpklshs:
9607 case Intrinsic::s390_vpklsfs:
9608 case Intrinsic::s390_vpklsgs:
9609 case Intrinsic::s390_vpdi:
9610 case Intrinsic::s390_vsldb:
9611 case Intrinsic::s390_vperm:
9614 case Intrinsic::s390_vuplhb:
9615 case Intrinsic::s390_vuplhh:
9616 case Intrinsic::s390_vuplhf:
9617 case Intrinsic::s390_vupllb:
9618 case Intrinsic::s390_vupllh:
9619 case Intrinsic::s390_vupllf:
9622 case Intrinsic::s390_vuphb:
9623 case Intrinsic::s390_vuphh:
9624 case Intrinsic::s390_vuphf:
9625 case Intrinsic::s390_vuplb:
9626 case Intrinsic::s390_vuplhw:
9627 case Intrinsic::s390_vuplf: {
9642 case SystemZISD::JOIN_DWORDS:
9643 case SystemZISD::SELECT_CCMASK:
9646 case SystemZISD::REPLICATE: {
9669 if (
LHS == 1)
return 1;
9672 if (
RHS == 1)
return 1;
9673 unsigned Common = std::min(
LHS,
RHS);
9674 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9675 EVT VT =
Op.getValueType();
9677 if (SrcBitWidth > VTBits) {
9678 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9679 if (Common > SrcExtraBits)
9680 return (Common - SrcExtraBits);
9683 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9690 unsigned Depth)
const {
9691 if (
Op.getResNo() != 0)
9693 unsigned Opcode =
Op.getOpcode();
9695 unsigned Id =
Op.getConstantOperandVal(0);
9697 case Intrinsic::s390_vpksh:
9698 case Intrinsic::s390_vpksf:
9699 case Intrinsic::s390_vpksg:
9700 case Intrinsic::s390_vpkshs:
9701 case Intrinsic::s390_vpksfs:
9702 case Intrinsic::s390_vpksgs:
9703 case Intrinsic::s390_vpklsh:
9704 case Intrinsic::s390_vpklsf:
9705 case Intrinsic::s390_vpklsg:
9706 case Intrinsic::s390_vpklshs:
9707 case Intrinsic::s390_vpklsfs:
9708 case Intrinsic::s390_vpklsgs:
9709 case Intrinsic::s390_vpdi:
9710 case Intrinsic::s390_vsldb:
9711 case Intrinsic::s390_vperm:
9713 case Intrinsic::s390_vuphb:
9714 case Intrinsic::s390_vuphh:
9715 case Intrinsic::s390_vuphf:
9716 case Intrinsic::s390_vuplb:
9717 case Intrinsic::s390_vuplhw:
9718 case Intrinsic::s390_vuplf: {
9722 EVT VT =
Op.getValueType();
9732 case SystemZISD::SELECT_CCMASK:
9745 switch (
Op->getOpcode()) {
9746 case SystemZISD::PCREL_WRAPPER:
9747 case SystemZISD::PCREL_OFFSET:
9758 "Unexpected stack alignment");
9761 unsigned StackProbeSize =
9764 StackProbeSize &= ~(StackAlign - 1);
9765 return StackProbeSize ? StackProbeSize : StackAlign;
9804 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9806 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9812 if (miI ==
MBB->end()) {
9814 if (Succ->isLiveIn(SystemZ::CC))
9825 switch (
MI.getOpcode()) {
9826 case SystemZ::Select32:
9827 case SystemZ::Select64:
9828 case SystemZ::Select128:
9829 case SystemZ::SelectF32:
9830 case SystemZ::SelectF64:
9831 case SystemZ::SelectF128:
9832 case SystemZ::SelectVR32:
9833 case SystemZ::SelectVR64:
9834 case SystemZ::SelectVR128:
9866 for (
auto *
MI : Selects) {
9867 Register DestReg =
MI->getOperand(0).getReg();
9868 Register TrueReg =
MI->getOperand(1).getReg();
9869 Register FalseReg =
MI->getOperand(2).getReg();
9874 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9877 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9878 TrueReg = It->second.first;
9880 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9881 FalseReg = It->second.second;
9884 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9889 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9900 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9901 assert(TFL->hasReservedCallFrame(MF) &&
9902 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9907 uint32_t NumBytes =
MI.getOperand(0).getImm();
9912 MI.eraseFromParent();
9921 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9923 unsigned CCValid =
MI.getOperand(3).getImm();
9924 unsigned CCMask =
MI.getOperand(4).getImm();
9929 SmallVector<MachineInstr*, 8> Selects;
9930 SmallVector<MachineInstr*, 8> DbgValues;
9936 assert(NextMI.getOperand(3).getImm() == CCValid &&
9937 "Bad CCValid operands since CC was not redefined.");
9938 if (NextMI.getOperand(4).getImm() == CCMask ||
9939 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9945 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9946 NextMI.usesCustomInsertionHook())
9949 for (
auto *SelMI : Selects)
9950 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9954 if (NextMI.isDebugInstr()) {
9956 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9959 }
else if (User || ++
Count > 20)
9963 MachineInstr *LastMI = Selects.back();
9964 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9966 MachineBasicBlock *StartMBB =
MBB;
9996 for (
auto *SelMI : Selects)
9997 SelMI->eraseFromParent();
10000 for (
auto *DbgMI : DbgValues)
10001 MBB->
splice(InsertPos, StartMBB, DbgMI);
10012 unsigned StoreOpcode,
10013 unsigned STOCOpcode,
10014 bool Invert)
const {
10015 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10017 Register SrcReg =
MI.getOperand(0).getReg();
10018 MachineOperand
Base =
MI.getOperand(1);
10019 int64_t Disp =
MI.getOperand(2).getImm();
10020 Register IndexReg =
MI.getOperand(3).getReg();
10021 unsigned CCValid =
MI.getOperand(4).getImm();
10022 unsigned CCMask =
MI.getOperand(5).getImm();
10025 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10029 MachineMemOperand *MMO =
nullptr;
10030 for (
auto *
I :
MI.memoperands())
10031 if (
I->isStore()) {
10039 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10051 MI.eraseFromParent();
10059 MachineBasicBlock *StartMBB =
MBB;
10065 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10092 MI.eraseFromParent();
10102 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10110 MachineBasicBlock *StartMBB =
MBB;
10128 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10155 MI.eraseFromParent();
10166 bool Invert)
const {
10168 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10175 int64_t Disp =
MI.getOperand(2).getImm();
10177 Register BitShift =
MI.getOperand(4).getReg();
10178 Register NegBitShift =
MI.getOperand(5).getReg();
10179 unsigned BitSize =
MI.getOperand(6).getImm();
10183 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10184 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10185 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10195 MachineBasicBlock *StartMBB =
MBB;
10228 }
else if (BinOpcode)
10251 MI.eraseFromParent();
10262 unsigned KeepOldMask)
const {
10264 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10270 int64_t Disp =
MI.getOperand(2).getImm();
10272 Register BitShift =
MI.getOperand(4).getReg();
10273 Register NegBitShift =
MI.getOperand(5).getReg();
10274 unsigned BitSize =
MI.getOperand(6).getImm();
10278 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10279 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10280 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10291 MachineBasicBlock *StartMBB =
MBB;
10355 MI.eraseFromParent();
10365 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10371 int64_t Disp =
MI.getOperand(2).getImm();
10372 Register CmpVal =
MI.getOperand(3).getReg();
10373 Register OrigSwapVal =
MI.getOperand(4).getReg();
10374 Register BitShift =
MI.getOperand(5).getReg();
10375 Register NegBitShift =
MI.getOperand(6).getReg();
10376 int64_t BitSize =
MI.getOperand(7).getImm();
10382 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10383 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10384 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10385 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10397 MachineBasicBlock *StartMBB =
MBB;
10469 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10472 MI.eraseFromParent();
10480 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10485 .
add(
MI.getOperand(1))
10486 .
addImm(SystemZ::subreg_h64)
10487 .
add(
MI.getOperand(2))
10488 .
addImm(SystemZ::subreg_l64);
10489 MI.eraseFromParent();
10498 bool ClearEven)
const {
10500 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10522 MI.eraseFromParent();
10529 unsigned Opcode,
bool IsMemset)
const {
10531 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10536 uint64_t DestDisp =
MI.getOperand(1).getImm();
10541 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10544 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10554 SrcDisp =
MI.getOperand(3).getImm();
10556 SrcBase = DestBase;
10557 SrcDisp = DestDisp++;
10558 foldDisplIfNeeded(DestBase, DestDisp);
10561 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10562 bool IsImmForm = LengthMO.
isImm();
10563 bool IsRegForm = !IsImmForm;
10566 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10568 MachineOperand DBase, uint64_t DDisp,
10569 MachineOperand
SBase, uint64_t SDisp,
10570 unsigned Length) ->
void {
10574 if (ByteMO.
isImm())
10589 bool NeedsLoop =
false;
10590 uint64_t ImmLength = 0;
10591 Register LenAdjReg = SystemZ::NoRegister;
10593 ImmLength = LengthMO.
getImm();
10594 ImmLength += IsMemset ? 2 : 1;
10595 if (ImmLength == 0) {
10596 MI.eraseFromParent();
10599 if (Opcode == SystemZ::CLC) {
10600 if (ImmLength > 3 * 256)
10610 }
else if (ImmLength > 6 * 256)
10618 LenAdjReg = LengthMO.
getReg();
10623 MachineBasicBlock *EndMBB =
10624 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10632 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10642 auto loadZeroAddress = [&]() -> MachineOperand {
10647 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10648 DestBase = loadZeroAddress();
10649 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10650 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10652 MachineBasicBlock *StartMBB =
nullptr;
10653 MachineBasicBlock *LoopMBB =
nullptr;
10654 MachineBasicBlock *NextMBB =
nullptr;
10655 MachineBasicBlock *DoneMBB =
nullptr;
10656 MachineBasicBlock *AllDoneMBB =
nullptr;
10660 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10669 RC = &SystemZ::GR64BitRegClass;
10697 MBB = MemsetOneCheckMBB;
10708 MBB = MemsetOneMBB;
10740 if (EndMBB && !ImmLength)
10762 if (!HaveSingleBase)
10769 if (Opcode == SystemZ::MVC)
10796 if (!HaveSingleBase)
10819 Register RemDestReg = HaveSingleBase ? RemSrcReg
10824 if (!HaveSingleBase)
10832 MachineInstrBuilder EXRL_MIB =
10840 if (Opcode != SystemZ::MVC) {
10850 while (ImmLength > 0) {
10851 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10854 foldDisplIfNeeded(DestBase, DestDisp);
10855 foldDisplIfNeeded(SrcBase, SrcDisp);
10856 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10857 DestDisp += ThisLength;
10858 SrcDisp += ThisLength;
10859 ImmLength -= ThisLength;
10862 if (EndMBB && ImmLength > 0) {
10878 MI.eraseFromParent();
10885 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10890 uint64_t
Len =
MI.getOperand(2).getImm();
10891 assert(Len > 0 && Len <= 256 &&
"Memmove of of unsupported constant length.");
10920 MI.eraseFromParent();
10929 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10933 uint64_t End1Reg =
MI.getOperand(0).getReg();
10934 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10935 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10936 uint64_t CharReg =
MI.getOperand(3).getReg();
10943 MachineBasicBlock *StartMBB =
MBB;
10979 MI.eraseFromParent();
10986 bool NoFloat)
const {
10988 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10989 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10992 MI.setDesc(
TII->get(Opcode));
10996 uint64_t Control =
MI.getOperand(2).getImm();
10997 static const unsigned GPRControlBit[16] = {
10998 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10999 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
11001 Control |= GPRControlBit[15];
11002 if (TFI->
hasFP(MF))
11003 Control |= GPRControlBit[11];
11004 MI.getOperand(2).setImm(Control);
11007 for (
int I = 0;
I < 16;
I++) {
11008 if ((Control & GPRControlBit[
I]) == 0) {
11015 if (!NoFloat && (Control & 4) != 0) {
11016 if (Subtarget.hasVector()) {
11033 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11034 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11037 Register SrcReg =
MI.getOperand(0).getReg();
11048 MI.eraseFromParent();
11056 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11057 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11060 Register DstReg =
MI.getOperand(0).getReg();
11061 Register SizeReg =
MI.getOperand(2).getReg();
11063 MachineBasicBlock *StartMBB =
MBB;
11139 MI.eraseFromParent();
11143SDValue SystemZTargetLowering::
11146 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11158 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11163 .
addImm(
MI.getOperand(1).getImm());
11164 MI.eraseFromParent();
11170 switch (
MI.getOpcode()) {
11171 case SystemZ::ADJCALLSTACKDOWN:
11172 case SystemZ::ADJCALLSTACKUP:
11173 return emitAdjCallStack(
MI,
MBB);
11175 case SystemZ::Select32:
11176 case SystemZ::Select64:
11177 case SystemZ::Select128:
11178 case SystemZ::SelectF32:
11179 case SystemZ::SelectF64:
11180 case SystemZ::SelectF128:
11181 case SystemZ::SelectVR32:
11182 case SystemZ::SelectVR64:
11183 case SystemZ::SelectVR128:
11184 return emitSelect(
MI,
MBB);
11186 case SystemZ::CondStore8Mux:
11187 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11188 case SystemZ::CondStore8MuxInv:
11189 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11190 case SystemZ::CondStore16Mux:
11191 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11192 case SystemZ::CondStore16MuxInv:
11193 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11194 case SystemZ::CondStore32Mux:
11195 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11196 case SystemZ::CondStore32MuxInv:
11197 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11198 case SystemZ::CondStore8:
11199 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11200 case SystemZ::CondStore8Inv:
11201 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11202 case SystemZ::CondStore16:
11203 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11204 case SystemZ::CondStore16Inv:
11205 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11206 case SystemZ::CondStore32:
11207 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11208 case SystemZ::CondStore32Inv:
11209 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11210 case SystemZ::CondStore64:
11211 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11212 case SystemZ::CondStore64Inv:
11213 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11214 case SystemZ::CondStoreF32:
11215 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11216 case SystemZ::CondStoreF32Inv:
11217 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11218 case SystemZ::CondStoreF64:
11219 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11220 case SystemZ::CondStoreF64Inv:
11221 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11223 case SystemZ::SCmp128Hi:
11224 return emitICmp128Hi(
MI,
MBB,
false);
11225 case SystemZ::UCmp128Hi:
11226 return emitICmp128Hi(
MI,
MBB,
true);
11228 case SystemZ::PAIR128:
11229 return emitPair128(
MI,
MBB);
11230 case SystemZ::AEXT128:
11231 return emitExt128(
MI,
MBB,
false);
11232 case SystemZ::ZEXT128:
11233 return emitExt128(
MI,
MBB,
true);
11235 case SystemZ::ATOMIC_SWAPW:
11236 return emitAtomicLoadBinary(
MI,
MBB, 0);
11238 case SystemZ::ATOMIC_LOADW_AR:
11239 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11240 case SystemZ::ATOMIC_LOADW_AFI:
11241 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11243 case SystemZ::ATOMIC_LOADW_SR:
11244 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11246 case SystemZ::ATOMIC_LOADW_NR:
11247 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11248 case SystemZ::ATOMIC_LOADW_NILH:
11249 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11251 case SystemZ::ATOMIC_LOADW_OR:
11252 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11253 case SystemZ::ATOMIC_LOADW_OILH:
11254 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11256 case SystemZ::ATOMIC_LOADW_XR:
11257 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11258 case SystemZ::ATOMIC_LOADW_XILF:
11259 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11261 case SystemZ::ATOMIC_LOADW_NRi:
11262 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11263 case SystemZ::ATOMIC_LOADW_NILHi:
11264 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11266 case SystemZ::ATOMIC_LOADW_MIN:
11268 case SystemZ::ATOMIC_LOADW_MAX:
11270 case SystemZ::ATOMIC_LOADW_UMIN:
11272 case SystemZ::ATOMIC_LOADW_UMAX:
11275 case SystemZ::ATOMIC_CMP_SWAPW:
11276 return emitAtomicCmpSwapW(
MI,
MBB);
11277 case SystemZ::MVCImm:
11278 case SystemZ::MVCReg:
11279 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11280 case SystemZ::NCImm:
11281 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11282 case SystemZ::OCImm:
11283 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11284 case SystemZ::XCImm:
11285 case SystemZ::XCReg:
11286 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11287 case SystemZ::CLCImm:
11288 case SystemZ::CLCReg:
11289 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11290 case SystemZ::MemsetImmImm:
11291 case SystemZ::MemsetImmReg:
11292 case SystemZ::MemsetRegImm:
11293 case SystemZ::MemsetRegReg:
11294 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11295 case SystemZ::MemmoveImm:
11296 return emitMemmoveImm(
MI,
MBB);
11297 case SystemZ::CLSTLoop:
11298 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11299 case SystemZ::MVSTLoop:
11300 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11301 case SystemZ::SRSTLoop:
11302 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11303 case SystemZ::TBEGIN:
11304 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11305 case SystemZ::TBEGIN_nofloat:
11306 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11307 case SystemZ::TBEGINC:
11308 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11309 case SystemZ::LTEBRCompare_Pseudo:
11310 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11311 case SystemZ::LTDBRCompare_Pseudo:
11312 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11313 case SystemZ::LTXBRCompare_Pseudo:
11314 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11316 case SystemZ::PROBED_ALLOCA:
11317 return emitProbedAlloca(
MI,
MBB);
11318 case SystemZ::EH_SjLj_SetJmp:
11320 case SystemZ::EH_SjLj_LongJmp:
11323 case TargetOpcode::STACKMAP:
11324 case TargetOpcode::PATCHPOINT:
11327 case SystemZ::MOV_STACKGUARD_DAG:
11328 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11330 case SystemZ::CMP_STACKGUARD_DAG:
11331 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11341SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11342 if (VT == MVT::Untyped)
11343 return &SystemZ::ADDR128BitRegClass;
11369 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11389 EVT VT =
Op.getValueType();
11390 Op =
Op.getOperand(0);
11391 EVT OpVT =
Op.getValueType();
11393 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11404 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11424 const AttributeList &Attrs =
F->getAttributes();
11425 if (Attrs.hasRetAttrs())
11426 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11427 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11428 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11431 OS << *FT->getParamType(
I);
11433 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11440bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11441 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11442 if (Itr == IsInternalCache.end())
11443 Itr = IsInternalCache
11444 .insert(std::pair<const Function *, bool>(
11447 return Itr->second;
11450void SystemZTargetLowering::
11458 bool IsInternal =
false;
11459 const Function *CalleeFn =
nullptr;
11462 IsInternal = isInternal(CalleeFn);
11463 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11464 errs() <<
"ERROR: Missing extension attribute of passed "
11465 <<
"value in call to function:\n" <<
"Callee: ";
11466 if (CalleeFn !=
nullptr)
11470 errs() <<
"Caller: ";
11476void SystemZTargetLowering::
11484 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11485 errs() <<
"ERROR: Missing extension attribute of returned "
11486 <<
"value from function:\n";
11494bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11496 if (!Subtarget.isTargetELF())
11505 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11506 MVT VT = Outs[i].VT;
11507 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11510 "Unexpected integer argument VT.");
11511 if (VT == MVT::i32 &&
11522 StringRef GuardMode = M.getStackProtectorGuard();
11525 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
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 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).
@ 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.
@ POISON
POISON - A poison node.
@ 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.
@ PSEUDO_FMIN
PSEUDO_FMIN is strictly equivalent to op0 olt op1 ?
@ 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.
@ Load
The value being inserted comes from a load (InsertElement only).
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.