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)
937 auto TryValue = [&](uint64_t
Value) ->
bool {
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,
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);
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)
1781 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
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.");
2155 }
else if (Subtarget.isTargetXPLINK64() &&
2158 Ins[
I].ArgVT.isSimple()) {
2163 MVT OrigVT = Ins[
I].ArgVT.getSimpleVT();
2169 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2175 Subtarget.getSpecialRegisters());
2181 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2186 if (IsVarArg && Subtarget.isTargetELF()) {
2199 int64_t RegSaveOffset =
2214 &SystemZ::FP64BitRegClass);
2226 if (Subtarget.isTargetXPLINK64()) {
2231 Subtarget.getSpecialRegisters());
2232 MRI.
addLiveIn(Regs->getADARegister(), ADAvReg);
2244 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2251 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2253 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2260 unsigned Offset,
bool LoadAdr =
false) {
2283 bool LoadAddr =
false;
2305 unsigned ADADelta = 0;
2306 unsigned EPADelta = 8;
2312 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2313 G->getGlobal()->hasPrivateLinkage());
2320 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2366 if (Subtarget.isTargetXPLINK64())
2370 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2374 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2393 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2401 unsigned NumParts = 1;
2405 SlotVT = Outs[
I].VT;
2412 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2415 assert(Outs[
I].PartOffset == 0);
2416 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2419 unsigned PartOffset = Outs[
I].PartOffset;
2425 assert(PartOffset &&
"Offset should be non-zero.");
2427 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2429 ArgValue = SpillSlot;
2446 if (!StackPtr.getNode())
2453 else if (VA.
getLocVT() == MVT::f16)
2466 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2470 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2476 if (!MemOpChains.
empty())
2484 if (Subtarget.isTargetXPLINK64()) {
2489 ->getAddressOfCalleeRegister();
2492 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2499 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2502 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2503 }
else if (IsTailCall) {
2506 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2511 for (
const auto &[Reg,
N] : RegsToPass) {
2518 Ops.push_back(Chain);
2519 Ops.push_back(Callee);
2523 for (
const auto &[Reg,
N] : RegsToPass)
2528 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2529 assert(Mask &&
"Missing call preserved mask for calling convention");
2534 Ops.push_back(Glue);
2543 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2553 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2560 VA.getLocVT(), Glue);
2577 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2579 Args.reserve(
Ops.size());
2585 Entry.IsZExt = !Entry.IsSExt;
2586 Args.push_back(Entry);
2597 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2608 const Type *RetTy)
const {
2611 for (
auto &Out : Outs)
2612 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2616 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2617 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2629 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2637 if (RetLocs.
empty())
2638 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2647 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2669 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2676 unsigned &CCValid) {
2677 unsigned Id =
Op.getConstantOperandVal(1);
2679 case Intrinsic::s390_tbegin:
2680 Opcode = SystemZISD::TBEGIN;
2684 case Intrinsic::s390_tbegin_nofloat:
2685 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2689 case Intrinsic::s390_tend:
2690 Opcode = SystemZISD::TEND;
2703 unsigned Id =
Op.getConstantOperandVal(0);
2705 case Intrinsic::s390_vpkshs:
2706 case Intrinsic::s390_vpksfs:
2707 case Intrinsic::s390_vpksgs:
2708 Opcode = SystemZISD::PACKS_CC;
2712 case Intrinsic::s390_vpklshs:
2713 case Intrinsic::s390_vpklsfs:
2714 case Intrinsic::s390_vpklsgs:
2715 Opcode = SystemZISD::PACKLS_CC;
2719 case Intrinsic::s390_vceqbs:
2720 case Intrinsic::s390_vceqhs:
2721 case Intrinsic::s390_vceqfs:
2722 case Intrinsic::s390_vceqgs:
2723 case Intrinsic::s390_vceqqs:
2724 Opcode = SystemZISD::VICMPES;
2728 case Intrinsic::s390_vchbs:
2729 case Intrinsic::s390_vchhs:
2730 case Intrinsic::s390_vchfs:
2731 case Intrinsic::s390_vchgs:
2732 case Intrinsic::s390_vchqs:
2733 Opcode = SystemZISD::VICMPHS;
2737 case Intrinsic::s390_vchlbs:
2738 case Intrinsic::s390_vchlhs:
2739 case Intrinsic::s390_vchlfs:
2740 case Intrinsic::s390_vchlgs:
2741 case Intrinsic::s390_vchlqs:
2742 Opcode = SystemZISD::VICMPHLS;
2746 case Intrinsic::s390_vtm:
2747 Opcode = SystemZISD::VTM;
2751 case Intrinsic::s390_vfaebs:
2752 case Intrinsic::s390_vfaehs:
2753 case Intrinsic::s390_vfaefs:
2754 Opcode = SystemZISD::VFAE_CC;
2758 case Intrinsic::s390_vfaezbs:
2759 case Intrinsic::s390_vfaezhs:
2760 case Intrinsic::s390_vfaezfs:
2761 Opcode = SystemZISD::VFAEZ_CC;
2765 case Intrinsic::s390_vfeebs:
2766 case Intrinsic::s390_vfeehs:
2767 case Intrinsic::s390_vfeefs:
2768 Opcode = SystemZISD::VFEE_CC;
2772 case Intrinsic::s390_vfeezbs:
2773 case Intrinsic::s390_vfeezhs:
2774 case Intrinsic::s390_vfeezfs:
2775 Opcode = SystemZISD::VFEEZ_CC;
2779 case Intrinsic::s390_vfenebs:
2780 case Intrinsic::s390_vfenehs:
2781 case Intrinsic::s390_vfenefs:
2782 Opcode = SystemZISD::VFENE_CC;
2786 case Intrinsic::s390_vfenezbs:
2787 case Intrinsic::s390_vfenezhs:
2788 case Intrinsic::s390_vfenezfs:
2789 Opcode = SystemZISD::VFENEZ_CC;
2793 case Intrinsic::s390_vistrbs:
2794 case Intrinsic::s390_vistrhs:
2795 case Intrinsic::s390_vistrfs:
2796 Opcode = SystemZISD::VISTR_CC;
2800 case Intrinsic::s390_vstrcbs:
2801 case Intrinsic::s390_vstrchs:
2802 case Intrinsic::s390_vstrcfs:
2803 Opcode = SystemZISD::VSTRC_CC;
2807 case Intrinsic::s390_vstrczbs:
2808 case Intrinsic::s390_vstrczhs:
2809 case Intrinsic::s390_vstrczfs:
2810 Opcode = SystemZISD::VSTRCZ_CC;
2814 case Intrinsic::s390_vstrsb:
2815 case Intrinsic::s390_vstrsh:
2816 case Intrinsic::s390_vstrsf:
2817 Opcode = SystemZISD::VSTRS_CC;
2821 case Intrinsic::s390_vstrszb:
2822 case Intrinsic::s390_vstrszh:
2823 case Intrinsic::s390_vstrszf:
2824 Opcode = SystemZISD::VSTRSZ_CC;
2828 case Intrinsic::s390_vfcedbs:
2829 case Intrinsic::s390_vfcesbs:
2830 Opcode = SystemZISD::VFCMPES;
2834 case Intrinsic::s390_vfchdbs:
2835 case Intrinsic::s390_vfchsbs:
2836 Opcode = SystemZISD::VFCMPHS;
2840 case Intrinsic::s390_vfchedbs:
2841 case Intrinsic::s390_vfchesbs:
2842 Opcode = SystemZISD::VFCMPHES;
2846 case Intrinsic::s390_vftcidb:
2847 case Intrinsic::s390_vftcisb:
2848 Opcode = SystemZISD::VFTCI;
2852 case Intrinsic::s390_tdc:
2853 Opcode = SystemZISD::TDC;
2866 unsigned NumOps =
Op.getNumOperands();
2869 Ops.push_back(
Op.getOperand(0));
2871 Ops.push_back(
Op.getOperand(
I));
2873 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2887 unsigned NumOps =
Op.getNumOperands();
2893 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2894 "Unhandled intrinsic with f16 operand.");
2897 Ops.push_back(CurrOper);
2911 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2912 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2913 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2939 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2942 int64_t
Value = ConstOp1->getSExtValue();
2958 if (!
C.Op0.hasOneUse() ||
2965 unsigned NumBits =
Load->getMemoryVT().getSizeInBits();
2966 if ((NumBits != 8 && NumBits != 16) ||
2967 NumBits !=
Load->getMemoryVT().getStoreSizeInBits())
2973 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2976 uint64_t Mask = (1 << NumBits) - 1;
2979 int64_t SignedValue = ConstOp1->getSExtValue();
2986 }
else if (NumBits == 8) {
3012 if (
C.Op0.getValueType() != MVT::i32 ||
3013 Load->getExtensionType() != ExtType) {
3015 Load->getBasePtr(),
Load->getPointerInfo(),
3016 Load->getMemoryVT(),
Load->getAlign(),
3017 Load->getMemOperand()->getFlags());
3023 if (
C.Op1.getValueType() != MVT::i32 ||
3024 Value != ConstOp1->getZExtValue())
3034 if (
Load->getMemoryVT() == MVT::i8)
3037 switch (
Load->getExtensionType()) {
3055 if (
C.Op0.isMachineOpcode() &&
3056 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3060 if (
C.Op0.getValueType() == MVT::i128)
3062 if (
C.Op0.getValueType() == MVT::f128)
3074 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3103 unsigned Opcode0 =
C.Op0.getOpcode();
3110 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3125 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3126 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3148 if (C1 && C1->isZero()) {
3167 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3170 if (C1 && C1->getZExtValue() == 32) {
3171 SDValue ShlOp0 =
C.Op0.getOperand(0);
3190 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3193 C.Op1->getAsZExtVal() == 0) {
3195 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3196 C.Op0.getValueSizeInBits().getFixedValue()) {
3197 unsigned Type = L->getExtensionType();
3200 C.Op0 =
C.Op0.getOperand(0);
3216 if (
C.Opcode != SystemZISD::ICMP)
3226 if (!
C.Op1.isMachineOpcode() ||
3227 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3232 C.Opcode = SystemZISD::CMP_STACKGUARD;
3243 uint64_t Amount = Shift->getZExtValue();
3244 if (Amount >=
N.getValueSizeInBits())
3259 unsigned ICmpType) {
3260 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3282 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3288 if (EffectivelyUnsigned && CmpVal <
Low) {
3296 if (CmpVal == Mask) {
3302 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3308 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3316 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3322 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3351 if (
C.Op0.getValueType() == MVT::i128) {
3357 if (Mask && Mask->getAPIntValue() == 0) {
3358 C.Opcode = SystemZISD::VTM;
3375 uint64_t CmpVal = ConstOp1->getZExtValue();
3382 NewC.Op0 =
C.Op0.getOperand(0);
3383 NewC.Op1 =
C.Op0.getOperand(1);
3387 MaskVal = Mask->getZExtValue();
3407 MaskVal = -(CmpVal & -CmpVal);
3416 unsigned NewCCMask, ShiftVal;
3420 (MaskVal >> ShiftVal != 0) &&
3421 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3423 MaskVal >> ShiftVal,
3427 MaskVal >>= ShiftVal;
3431 (MaskVal << ShiftVal != 0) &&
3432 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3434 MaskVal << ShiftVal,
3438 MaskVal <<= ShiftVal;
3447 C.Opcode = SystemZISD::TM;
3449 if (Mask && Mask->getZExtValue() == MaskVal)
3454 C.CCMask = NewCCMask;
3460 if (
C.Opcode != SystemZISD::ICMP)
3462 if (
C.Op0.getValueType() != MVT::i128)
3473 Src = Src.getOperand(0);
3476 unsigned Opcode = 0;
3477 if (Src.hasOneUse()) {
3478 switch (Src.getOpcode()) {
3479 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3480 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3481 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3482 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3483 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3484 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3490 C.Op0 = Src->getOperand(0);
3491 C.Op1 = Src->getOperand(1);
3495 C.CCMask ^=
C.CCValid;
3507 C.Opcode = SystemZISD::VICMPES;
3519 bool Swap =
false, Invert =
false;
3531 C.Opcode = SystemZISD::UCMP128HI;
3533 C.Opcode = SystemZISD::SCMP128HI;
3538 C.CCMask ^=
C.CCValid;
3549 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3552 if ((~
Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3555 C.Op0 =
C.Op0.getOperand(0);
3567 C.CCValid = CCValid;
3570 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3573 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3577 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3580 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3584 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3587 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3590 C.CCMask &= CCValid;
3598 bool IsSignaling =
false) {
3601 unsigned Opcode, CCValid;
3613 Comparison
C(CmpOp0, CmpOp1, Chain);
3615 if (
C.Op0.getValueType().isFloatingPoint()) {
3618 C.Opcode = SystemZISD::FCMP;
3619 else if (!IsSignaling)
3620 C.Opcode = SystemZISD::STRICT_FCMP;
3622 C.Opcode = SystemZISD::STRICT_FCMPS;
3627 C.Opcode = SystemZISD::ICMP;
3663 if (!
C.Op1.getNode()) {
3664 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3665 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3667 switch (
C.Op0.getOpcode()) {
3678 if (
C.Opcode == SystemZISD::ICMP)
3679 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3681 if (
C.Opcode == SystemZISD::TM) {
3684 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3687 if (
C.Opcode == SystemZISD::VICMPES ||
3688 C.Opcode == SystemZISD::VICMPHS ||
3689 C.Opcode == SystemZISD::VICMPHLS ||
3690 C.Opcode == SystemZISD::VFCMPES ||
3691 C.Opcode == SystemZISD::VFCMPHS ||
3692 C.Opcode == SystemZISD::VFCMPHES) {
3693 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3700 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3702 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3711 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3712 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3737 unsigned CCValid,
unsigned CCMask) {
3742 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3820 int Mask[] = { Start, -1, Start + 1, -1 };
3824 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3826 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3840 !Subtarget.hasVectorEnhancements1()) {
3846 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3847 SDValue HRes = DAG.
getNode(Opcode,
DL, VTs, Chain, H0, H1);
3848 SDValue LRes = DAG.
getNode(Opcode,
DL, VTs, Chain, L0, L1);
3849 SDValue Res = DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3854 SDValue
Ops[2] = { Res, NewChain };
3857 SDValue HRes = DAG.
getNode(Opcode,
DL, MVT::v2i64, H0, H1);
3858 SDValue LRes = DAG.
getNode(Opcode,
DL, MVT::v2i64, L0, L1);
3859 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3862 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3863 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3865 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3878 bool IsSignaling)
const {
3881 assert (!IsSignaling || Chain);
3884 bool Invert =
false;
3892 assert(IsFP &&
"Unexpected integer comparison");
3894 DL, VT, CmpOp1, CmpOp0, Chain);
3896 DL, VT, CmpOp0, CmpOp1, Chain);
3900 LT.getValue(1),
GE.getValue(1));
3909 assert(IsFP &&
"Unexpected integer comparison");
3911 DL, VT, CmpOp1, CmpOp0, Chain);
3913 DL, VT, CmpOp0, CmpOp1, Chain);
3917 LT.getValue(1),
GT.getValue(1));
3938 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3942 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3947 Chain =
Cmp.getValue(1);
3955 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3956 SDValue
Ops[2] = {
Cmp, Chain };
3964 SDValue CmpOp0 =
Op.getOperand(0);
3965 SDValue CmpOp1 =
Op.getOperand(1);
3968 EVT VT =
Op.getValueType();
3970 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3979 bool IsSignaling)
const {
3980 SDValue Chain =
Op.getOperand(0);
3981 SDValue CmpOp0 =
Op.getOperand(1);
3982 SDValue CmpOp1 =
Op.getOperand(2);
3985 EVT VT =
Op.getNode()->getValueType(0);
3987 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3988 Chain, IsSignaling);
4002 SDValue CmpOp0 =
Op.getOperand(2);
4003 SDValue CmpOp1 =
Op.getOperand(3);
4004 SDValue Dest =
Op.getOperand(4);
4010 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4044 C.CCMask ^=
C.CCValid;
4052 Op = SystemZISD::VICMPE;
4056 Op = SystemZISD::VICMPHL;
4058 Op = SystemZISD::VICMPH;
4073 SDValue CmpOp0 =
Op.getOperand(0);
4074 SDValue CmpOp1 =
Op.getOperand(1);
4075 SDValue TrueOp =
Op.getOperand(2);
4076 SDValue FalseOp =
Op.getOperand(3);
4097 C.Op1->getAsZExtVal() == 0) {
4104 if (Subtarget.hasVectorEnhancements3() &&
4105 C.Opcode == SystemZISD::ICMP &&
4106 C.Op0.getValueType() == MVT::i128 &&
4112 SDValue
Ops[] = {TrueOp, FalseOp,
4116 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4122 const GlobalValue *GV =
Node->getGlobal();
4128 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4150 }
else if (Subtarget.isTargetELF()) {
4155 }
else if (Subtarget.isTargetzOS()) {
4186 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4191 Ops.push_back(Chain);
4193 Node->getValueType(0),
4202 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4203 const uint32_t *
Mask =
4205 assert(Mask &&
"Missing call preserved mask for calling convention");
4209 Ops.push_back(Glue);
4212 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4220SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4244 const GlobalValue *GV =
Node->getGlobal();
4252 SDValue TP = lowerThreadPointer(
DL, DAG);
4259 SystemZConstantPoolValue *CPV =
4268 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4274 SystemZConstantPoolValue *CPV =
4283 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4288 SystemZMachineFunctionInfo* MFI =
4317 SystemZConstantPoolValue *CPV =
4351 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4368 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4373 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4375 MachineFrameInfo &MFI = MF.getFrameInfo();
4379 unsigned Depth =
Op.getConstantOperandVal(0);
4386 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4391 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4397 MachinePointerInfo());
4412 unsigned Depth =
Op.getConstantOperandVal(0);
4417 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4420 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4421 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4422 int Offset = TFL->getReturnAddressOffset(MF);
4426 MachinePointerInfo());
4431 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4433 &SystemZ::GR64BitRegClass);
4440 SDValue
In =
Op.getOperand(0);
4441 EVT InVT =
In.getValueType();
4442 EVT ResVT =
Op.getValueType();
4449 SDValue NewLoad = DAG.
getLoad(ResVT,
DL, LoadN->getChain(),
4450 LoadN->getBasePtr(), LoadN->getMemOperand());
4456 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4458 if (Subtarget.hasHighWord()) {
4462 MVT::i64, SDValue(U64, 0), In);
4470 DL, MVT::f32, Out64);
4472 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4475 MVT::f64, SDValue(U64, 0), In);
4477 if (Subtarget.hasHighWord())
4490 if (Subtarget.isTargetXPLINK64())
4491 return lowerVASTART_XPLINK(
Op, DAG);
4493 return lowerVASTART_ELF(
Op, DAG);
4499 SystemZMachineFunctionInfo *FuncInfo =
4500 MF.
getInfo<SystemZMachineFunctionInfo>();
4510 MachinePointerInfo(SV));
4516 SystemZMachineFunctionInfo *FuncInfo =
4517 MF.
getInfo<SystemZMachineFunctionInfo>();
4520 SDValue Chain =
Op.getOperand(0);
4521 SDValue Addr =
Op.getOperand(1);
4526 const unsigned NumFields = 4;
4527 SDValue Fields[NumFields] = {
4535 SDValue MemOps[NumFields];
4537 for (
unsigned I = 0;
I < NumFields; ++
I) {
4538 SDValue FieldAddr = Addr;
4542 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4543 MachinePointerInfo(SV,
Offset));
4551 SDValue Chain =
Op.getOperand(0);
4552 SDValue DstPtr =
Op.getOperand(1);
4553 SDValue SrcPtr =
Op.getOperand(2);
4563 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4564 MachinePointerInfo(SrcSV));
4568SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4570 if (Subtarget.isTargetXPLINK64())
4571 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4573 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4577SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4579 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4582 SDValue Chain =
Op.getOperand(0);
4583 SDValue
Size =
Op.getOperand(1);
4584 SDValue
Align =
Op.getOperand(2);
4589 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4592 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4593 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4595 SDValue NeededSpace =
Size;
4599 if (ExtraAlignSpace)
4603 bool IsSigned =
false;
4604 bool DoesNotReturn =
false;
4605 bool IsReturnValueUsed =
false;
4606 EVT VT =
Op.getValueType();
4607 SDValue AllocaCall =
4616 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4619 SDValue Glue = AllocaCall.
getValue(2);
4624 SDValue ArgAdjust = DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, PtrMVT);
4628 if (ExtraAlignSpace) {
4640SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4642 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4645 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4647 SDValue Chain =
Op.getOperand(0);
4648 SDValue
Size =
Op.getOperand(1);
4649 SDValue
Align =
Op.getOperand(2);
4654 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4657 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4658 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4661 SDValue NeededSpace =
Size;
4669 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4670 MachinePointerInfo());
4673 if (ExtraAlignSpace)
4680 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4681 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4693 SDValue ArgAdjust = DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4697 if (RequiredAlign > StackAlign) {
4707 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4708 MachinePointerInfo());
4714SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4718 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4723 unsigned Opcode)
const {
4724 EVT VT =
Op.getValueType();
4730 assert(Subtarget.hasMiscellaneousExtensions2());
4735 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4741 EVT VT =
Op.getValueType();
4749 else if (Subtarget.hasMiscellaneousExtensions2())
4754 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4770 SDValue LL =
Op.getOperand(0);
4771 SDValue RL =
Op.getOperand(1);
4789 EVT VT =
Op.getValueType();
4802 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4808 SDValue Op0 =
Op.getOperand(0);
4809 SDValue Op1 =
Op.getOperand(1);
4810 EVT VT =
Op.getValueType();
4830 EVT VT =
Op.getValueType();
4837 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4842 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4845 SDValue
Ops[] = {
Op.getOperand(0),
Op.getOperand(1)};
4852 Known[1].Zero.getZExtValue() };
4854 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4856 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4861 SDValue LowOp =
Ops[
Low];
4893 MVT::i64, HighOp, Low32);
4899 SDNode *
N =
Op.getNode();
4900 SDValue
LHS =
N->getOperand(0);
4901 SDValue
RHS =
N->getOperand(1);
4904 if (
N->getValueType(0) == MVT::i128) {
4905 unsigned BaseOp = 0;
4906 unsigned FlagOp = 0;
4907 bool IsBorrow =
false;
4908 switch (
Op.getOpcode()) {
4912 FlagOp = SystemZISD::VACC;
4916 FlagOp = SystemZISD::VSCBI;
4931 unsigned BaseOp = 0;
4932 unsigned CCValid = 0;
4933 unsigned CCMask = 0;
4935 switch (
Op.getOpcode()) {
4938 BaseOp = SystemZISD::SADDO;
4943 BaseOp = SystemZISD::SSUBO;
4948 BaseOp = SystemZISD::UADDO;
4953 BaseOp = SystemZISD::USUBO;
4959 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4963 if (
N->getValueType(1) == MVT::i1)
4989 SDNode *
N =
Op.getNode();
4990 MVT VT =
N->getSimpleValueType(0);
4996 SDValue
LHS =
N->getOperand(0);
4997 SDValue
RHS =
N->getOperand(1);
4998 SDValue Carry =
Op.getOperand(2);
5001 if (VT == MVT::i128) {
5002 unsigned BaseOp = 0;
5003 unsigned FlagOp = 0;
5004 bool IsBorrow =
false;
5005 switch (
Op.getOpcode()) {
5008 BaseOp = SystemZISD::VAC;
5009 FlagOp = SystemZISD::VACCC;
5012 BaseOp = SystemZISD::VSBI;
5013 FlagOp = SystemZISD::VSBCBI;
5032 unsigned BaseOp = 0;
5033 unsigned CCValid = 0;
5034 unsigned CCMask = 0;
5036 switch (
Op.getOpcode()) {
5042 BaseOp = SystemZISD::ADDCARRY;
5050 BaseOp = SystemZISD::SUBCARRY;
5061 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5065 if (
N->getValueType(1) == MVT::i1)
5073 EVT VT =
Op.getValueType();
5075 Op =
Op.getOperand(0);
5096 SDValue Tmp = DAG.
getNode(SystemZISD::VSHL_BY_SCALAR,
DL, VT,
Op, Shift);
5098 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5110 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5124 if (NumSignificantBits == 0)
5130 BitSize = std::min(BitSize, OrigBitSize);
5139 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5141 if (BitSize != OrigBitSize)
5178 EVT RegVT =
Op.getValueType();
5180 return lowerATOMIC_LDST_I128(
Op, DAG);
5181 return lowerLoadF16(
Op, DAG);
5187 if (
Node->getMemoryVT().getSizeInBits() == 128)
5188 return lowerATOMIC_LDST_I128(
Op, DAG);
5189 return lowerStoreF16(
Op, DAG);
5196 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5197 "Only custom lowering i128 or f128.");
5210 EVT WideVT = MVT::i32;
5233 unsigned Opcode)
const {
5237 EVT NarrowVT =
Node->getMemoryVT();
5238 EVT WideVT = MVT::i32;
5239 if (NarrowVT == WideVT)
5243 SDValue ChainIn =
Node->getChain();
5244 SDValue Addr =
Node->getBasePtr();
5246 MachineMemOperand *MMO =
Node->getMemOperand();
5250 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5252 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5254 Src2.getValueType());
5257 SDValue AlignedAddr, BitShift, NegBitShift;
5265 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5268 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5269 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5274 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5275 SDValue
Ops[] = { ChainIn, AlignedAddr,
Src2, BitShift, NegBitShift,
5295 EVT MemVT =
Node->getMemoryVT();
5296 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5298 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5299 assert(Subtarget.hasInterlockedAccess1() &&
5300 "Should have been expanded by AtomicExpand pass.");
5306 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5307 Node->getMemOperand());
5310 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5317 SDValue ChainIn =
Node->getOperand(0);
5318 SDValue Addr =
Node->getOperand(1);
5319 SDValue CmpVal =
Node->getOperand(2);
5320 SDValue SwapVal =
Node->getOperand(3);
5321 MachineMemOperand *MMO =
Node->getMemOperand();
5324 if (
Node->getMemoryVT() == MVT::i128) {
5333 EVT NarrowVT =
Node->getMemoryVT();
5334 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5335 if (NarrowVT == WideVT) {
5336 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5337 SDValue
Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5339 DL, Tys,
Ops, NarrowVT, MMO);
5353 SDValue AlignedAddr, BitShift, NegBitShift;
5357 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5358 SDValue
Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5361 VTList,
Ops, NarrowVT, MMO);
5375SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5398 auto *Regs = Subtarget.getSpecialRegisters();
5401 "in GHC calling convention");
5403 Regs->getStackPointerRegister(),
Op.getValueType());
5409 auto *Regs = Subtarget.getSpecialRegisters();
5410 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5414 "in GHC calling convention");
5416 SDValue Chain =
Op.getOperand(0);
5417 SDValue NewSP =
Op.getOperand(1);
5421 if (StoreBackchain) {
5423 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5424 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5425 MachinePointerInfo());
5428 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5431 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5432 MachinePointerInfo());
5439 bool IsData =
Op.getConstantOperandVal(4);
5442 return Op.getOperand(0);
5445 bool IsWrite =
Op.getConstantOperandVal(2);
5452 Node->getMemoryVT(),
Node->getMemOperand());
5456SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5458 unsigned Opcode, CCValid;
5460 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5471SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5473 unsigned Opcode, CCValid;
5476 if (
Op->getNumValues() == 1)
5478 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5480 SDValue(Node, 0),
getCCResult(DAG, SDValue(Node, 1)));
5483 unsigned Id =
Op.getConstantOperandVal(0);
5485 case Intrinsic::thread_pointer:
5486 return lowerThreadPointer(SDLoc(
Op), DAG);
5488 case Intrinsic::s390_vpdi:
5489 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5490 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5492 case Intrinsic::s390_vperm:
5493 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5494 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5496 case Intrinsic::s390_vuphb:
5497 case Intrinsic::s390_vuphh:
5498 case Intrinsic::s390_vuphf:
5499 case Intrinsic::s390_vuphg:
5500 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5503 case Intrinsic::s390_vuplhb:
5504 case Intrinsic::s390_vuplhh:
5505 case Intrinsic::s390_vuplhf:
5506 case Intrinsic::s390_vuplhg:
5507 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5510 case Intrinsic::s390_vuplb:
5511 case Intrinsic::s390_vuplhw:
5512 case Intrinsic::s390_vuplf:
5513 case Intrinsic::s390_vuplg:
5514 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5517 case Intrinsic::s390_vupllb:
5518 case Intrinsic::s390_vupllh:
5519 case Intrinsic::s390_vupllf:
5520 case Intrinsic::s390_vupllg:
5521 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5524 case Intrinsic::s390_vsumb:
5525 case Intrinsic::s390_vsumh:
5526 case Intrinsic::s390_vsumgh:
5527 case Intrinsic::s390_vsumgf:
5528 case Intrinsic::s390_vsumqf:
5529 case Intrinsic::s390_vsumqg:
5530 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5531 Op.getOperand(1),
Op.getOperand(2));
5533 case Intrinsic::s390_vaq:
5535 Op.getOperand(1),
Op.getOperand(2));
5536 case Intrinsic::s390_vaccb:
5537 case Intrinsic::s390_vacch:
5538 case Intrinsic::s390_vaccf:
5539 case Intrinsic::s390_vaccg:
5540 case Intrinsic::s390_vaccq:
5541 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5542 Op.getOperand(1),
Op.getOperand(2));
5543 case Intrinsic::s390_vacq:
5544 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5545 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5546 case Intrinsic::s390_vacccq:
5547 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5548 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5550 case Intrinsic::s390_vsq:
5552 Op.getOperand(1),
Op.getOperand(2));
5553 case Intrinsic::s390_vscbib:
5554 case Intrinsic::s390_vscbih:
5555 case Intrinsic::s390_vscbif:
5556 case Intrinsic::s390_vscbig:
5557 case Intrinsic::s390_vscbiq:
5558 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5559 Op.getOperand(1),
Op.getOperand(2));
5560 case Intrinsic::s390_vsbiq:
5561 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5562 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5563 case Intrinsic::s390_vsbcbiq:
5564 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5565 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5567 case Intrinsic::s390_vmhb:
5568 case Intrinsic::s390_vmhh:
5569 case Intrinsic::s390_vmhf:
5570 case Intrinsic::s390_vmhg:
5571 case Intrinsic::s390_vmhq:
5573 Op.getOperand(1),
Op.getOperand(2));
5574 case Intrinsic::s390_vmlhb:
5575 case Intrinsic::s390_vmlhh:
5576 case Intrinsic::s390_vmlhf:
5577 case Intrinsic::s390_vmlhg:
5578 case Intrinsic::s390_vmlhq:
5580 Op.getOperand(1),
Op.getOperand(2));
5582 case Intrinsic::s390_vmahb:
5583 case Intrinsic::s390_vmahh:
5584 case Intrinsic::s390_vmahf:
5585 case Intrinsic::s390_vmahg:
5586 case Intrinsic::s390_vmahq:
5587 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5588 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5589 case Intrinsic::s390_vmalhb:
5590 case Intrinsic::s390_vmalhh:
5591 case Intrinsic::s390_vmalhf:
5592 case Intrinsic::s390_vmalhg:
5593 case Intrinsic::s390_vmalhq:
5594 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5595 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5597 case Intrinsic::s390_vmeb:
5598 case Intrinsic::s390_vmeh:
5599 case Intrinsic::s390_vmef:
5600 case Intrinsic::s390_vmeg:
5601 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5602 Op.getOperand(1),
Op.getOperand(2));
5603 case Intrinsic::s390_vmleb:
5604 case Intrinsic::s390_vmleh:
5605 case Intrinsic::s390_vmlef:
5606 case Intrinsic::s390_vmleg:
5607 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5608 Op.getOperand(1),
Op.getOperand(2));
5609 case Intrinsic::s390_vmob:
5610 case Intrinsic::s390_vmoh:
5611 case Intrinsic::s390_vmof:
5612 case Intrinsic::s390_vmog:
5613 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5614 Op.getOperand(1),
Op.getOperand(2));
5615 case Intrinsic::s390_vmlob:
5616 case Intrinsic::s390_vmloh:
5617 case Intrinsic::s390_vmlof:
5618 case Intrinsic::s390_vmlog:
5619 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5620 Op.getOperand(1),
Op.getOperand(2));
5622 case Intrinsic::s390_vmaeb:
5623 case Intrinsic::s390_vmaeh:
5624 case Intrinsic::s390_vmaef:
5625 case Intrinsic::s390_vmaeg:
5627 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5628 Op.getOperand(1),
Op.getOperand(2)),
5630 case Intrinsic::s390_vmaleb:
5631 case Intrinsic::s390_vmaleh:
5632 case Intrinsic::s390_vmalef:
5633 case Intrinsic::s390_vmaleg:
5635 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5636 Op.getOperand(1),
Op.getOperand(2)),
5638 case Intrinsic::s390_vmaob:
5639 case Intrinsic::s390_vmaoh:
5640 case Intrinsic::s390_vmaof:
5641 case Intrinsic::s390_vmaog:
5643 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5644 Op.getOperand(1),
Op.getOperand(2)),
5646 case Intrinsic::s390_vmalob:
5647 case Intrinsic::s390_vmaloh:
5648 case Intrinsic::s390_vmalof:
5649 case Intrinsic::s390_vmalog:
5651 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5652 Op.getOperand(1),
Op.getOperand(2)),
5673 { SystemZISD::MERGE_HIGH, 8,
5674 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5676 { SystemZISD::MERGE_HIGH, 4,
5677 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5679 { SystemZISD::MERGE_HIGH, 2,
5680 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5682 { SystemZISD::MERGE_HIGH, 1,
5683 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5685 { SystemZISD::MERGE_LOW, 8,
5686 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5688 { SystemZISD::MERGE_LOW, 4,
5689 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5691 { SystemZISD::MERGE_LOW, 2,
5692 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5694 { SystemZISD::MERGE_LOW, 1,
5695 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5697 { SystemZISD::PACK, 4,
5698 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5700 { SystemZISD::PACK, 2,
5701 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5703 { SystemZISD::PACK, 1,
5704 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5706 { SystemZISD::PERMUTE_DWORDS, 4,
5707 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5709 { SystemZISD::PERMUTE_DWORDS, 1,
5710 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5724 OpNo0 = OpNo1 = OpNos[1];
5725 }
else if (OpNos[1] < 0) {
5726 OpNo0 = OpNo1 = OpNos[0];
5744 unsigned &OpNo0,
unsigned &OpNo1) {
5745 int OpNos[] = { -1, -1 };
5758 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5760 OpNos[ModelOpNo] = RealOpNo;
5768 unsigned &OpNo0,
unsigned &OpNo1) {
5785 int Elt = Bytes[From];
5788 Transform[From] = -1;
5790 while (
P.Bytes[To] != Elt) {
5795 Transform[From] = To;
5819 Bytes.
resize(NumElements * BytesPerElement, -1);
5820 for (
unsigned I = 0;
I < NumElements; ++
I) {
5821 int Index = VSN->getMaskElt(
I);
5823 for (
unsigned J = 0; J < BytesPerElement; ++J)
5824 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5828 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5831 Bytes.
resize(NumElements * BytesPerElement, -1);
5832 for (
unsigned I = 0;
I < NumElements; ++
I)
5833 for (
unsigned J = 0; J < BytesPerElement; ++J)
5834 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5845 unsigned BytesPerElement,
int &
Base) {
5847 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5848 if (Bytes[Start +
I] >= 0) {
5849 unsigned Elem = Bytes[Start +
I];
5853 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5855 }
else if (
unsigned(
Base) != Elem -
I)
5868 unsigned &StartIndex,
unsigned &OpNo0,
5870 int OpNos[] = { -1, -1 };
5872 for (
unsigned I = 0;
I < 16; ++
I) {
5873 int Index = Bytes[
I];
5879 Shift = ExpectedShift;
5880 else if (Shift != ExpectedShift)
5884 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5886 OpNos[ModelOpNo] = RealOpNo;
5899 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5900 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5908 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5910 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5911 }
else if (
P.Opcode == SystemZISD::PACK) {
5914 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5923 N =
N->getOperand(0);
5926 return Op->getZExtValue() == 0;
5932 for (
unsigned I = 0;
I < Num ;
I++)
5944 for (
unsigned I = 0;
I < 2; ++
I)
5948 unsigned StartIndex, OpNo0, OpNo1;
5950 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5957 if (ZeroVecIdx != UINT32_MAX) {
5958 bool MaskFirst =
true;
5963 if (OpNo == ZeroVecIdx &&
I == 0) {
5968 if (OpNo != ZeroVecIdx && Byte == 0) {
5975 if (ZeroIdx != -1) {
5978 if (Bytes[
I] >= 0) {
5981 if (OpNo == ZeroVecIdx)
5993 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5996 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
6008 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
6014struct GeneralShuffle {
6015 GeneralShuffle(EVT vt)
6016 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
6018 bool add(SDValue,
unsigned);
6019 SDValue
getNode(SelectionDAG &,
const SDLoc &);
6020 void tryPrepareForUnpack();
6021 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6022 SDValue insertUnpackIfPrepared(SelectionDAG &DAG,
const SDLoc &
DL, SDValue
Op);
6036 unsigned UnpackFromEltSize;
6043void GeneralShuffle::addUndef() {
6045 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6046 Bytes.push_back(-1);
6055bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6061 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6066 if (FromBytesPerElement < BytesPerElement)
6070 (FromBytesPerElement - BytesPerElement));
6073 while (
Op.getNode()) {
6075 Op =
Op.getOperand(0);
6091 }
else if (
Op.isUndef()) {
6100 for (; OpNo <
Ops.size(); ++OpNo)
6101 if (
Ops[OpNo] ==
Op)
6103 if (OpNo ==
Ops.size())
6108 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6109 Bytes.push_back(
Base +
I);
6118 if (
Ops.size() == 0)
6122 tryPrepareForUnpack();
6125 if (
Ops.size() == 1)
6137 unsigned Stride = 1;
6138 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6139 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6149 else if (OpNo ==
I + Stride)
6160 if (NewBytes[J] >= 0) {
6162 "Invalid double permute");
6165 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6171 if (NewBytes[J] >= 0)
6187 unsigned OpNo0, OpNo1;
6191 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6196 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6203 dbgs() <<
Msg.c_str() <<
" { ";
6204 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6205 dbgs() << Bytes[
I] <<
" ";
6213void GeneralShuffle::tryPrepareForUnpack() {
6215 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6220 if (
Ops.size() > 2 &&
6225 UnpackFromEltSize = 1;
6226 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6227 bool MatchUnpack =
true;
6230 unsigned ToEltSize = UnpackFromEltSize * 2;
6231 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6234 if (Bytes[Elt] != -1) {
6236 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6237 MatchUnpack =
false;
6243 if (
Ops.size() == 2) {
6245 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6247 if (SrcBytes[i] == -1)
6249 if (SrcBytes[i] % 16 !=
int(i))
6250 CanUseUnpackHigh =
false;
6252 CanUseUnpackLow =
false;
6253 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6254 UnpackFromEltSize = UINT_MAX;
6258 if (!CanUseUnpackHigh)
6264 if (UnpackFromEltSize > 4)
6267 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6268 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6270 dumpBytes(Bytes,
"Original Bytes vector:"););
6279 Elt += UnpackFromEltSize;
6280 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6281 Bytes[
B] = Bytes[Elt];
6289 Ops.erase(&
Ops[ZeroVecOpNo]);
6291 if (Bytes[
I] >= 0) {
6293 if (OpNo > ZeroVecOpNo)
6304 if (!unpackWasPrepared())
6306 unsigned InBits = UnpackFromEltSize * 8;
6310 unsigned OutBits = InBits * 2;
6313 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6314 : SystemZISD::UNPACKL_HIGH,
6315 DL, OutVT, PackedOp);
6320 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6321 if (!
Op.getOperand(
I).isUndef())
6337 if (
Value.isUndef())
6349 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6352 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6353 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6374 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6390 GeneralShuffle GS(VT);
6392 bool FoundOne =
false;
6393 for (
unsigned I = 0;
I < NumElements; ++
I) {
6396 Op =
Op.getOperand(0);
6399 unsigned Elem =
Op.getConstantOperandVal(1);
6400 if (!GS.add(
Op.getOperand(0), Elem))
6403 }
else if (
Op.isUndef()) {
6417 if (!ResidueOps.
empty()) {
6418 while (ResidueOps.
size() < NumElements)
6420 for (
auto &
Op : GS.Ops) {
6421 if (!
Op.getNode()) {
6427 return GS.getNode(DAG,
SDLoc(BVN));
6430bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6436 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6447 "Handling full vectors only.");
6467 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6479 unsigned int NumElements = Elems.
size();
6480 unsigned int Count = 0;
6481 for (
auto Elem : Elems) {
6482 if (!Elem.isUndef()) {
6485 else if (Elem !=
Single) {
6509 bool AllLoads =
true;
6510 for (
auto Elem : Elems)
6511 if (!isVectorElementLoad(Elem)) {
6517 if (VT == MVT::v2i64 && !AllLoads)
6521 if (VT == MVT::v2f64 && !AllLoads)
6531 if (VT == MVT::v4f32 && !AllLoads)
6535 if (VT == MVT::v8f16 && !AllLoads) {
6544 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6553 unsigned NumConstants = 0;
6554 for (
unsigned I = 0;
I < NumElements; ++
I) {
6555 SDValue Elem = Elems[
I];
6567 SDValue ReplicatedVal;
6568 if (NumConstants > 0) {
6569 for (
unsigned I = 0;
I < NumElements; ++
I)
6580 std::map<const SDNode*, unsigned> UseCounts;
6581 SDNode *LoadMaxUses =
nullptr;
6582 for (
unsigned I = 0;
I < NumElements; ++
I)
6583 if (isVectorElementLoad(Elems[
I])) {
6584 SDNode *Ld = Elems[
I].getNode();
6585 unsigned Count = ++UseCounts[Ld];
6586 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6589 if (LoadMaxUses !=
nullptr) {
6590 ReplicatedVal = SDValue(LoadMaxUses, 0);
6594 unsigned I1 = NumElements / 2 - 1;
6595 unsigned I2 = NumElements - 1;
6596 bool Def1 = !Elems[
I1].isUndef();
6597 bool Def2 = !Elems[I2].isUndef();
6599 SDValue Elem1 = Elems[Def1 ?
I1 : I2];
6600 SDValue Elem2 = Elems[Def2 ? I2 :
I1];
6611 for (
unsigned I = 0;
I < NumElements; ++
I)
6612 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6622 EVT VT =
Op.getValueType();
6624 if (BVN->isConstant()) {
6625 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6643 for (
unsigned I = 0;
I < NumElements; ++
I)
6645 return buildVector(DAG,
DL, VT,
Ops);
6652 EVT VT =
Op.getValueType();
6655 if (VSN->isSplat()) {
6656 SDValue Op0 =
Op.getOperand(0);
6657 unsigned Index = VSN->getSplatIndex();
6659 "Splat index should be defined and in first operand");
6665 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6669 GeneralShuffle
GS(VT);
6670 for (
unsigned I = 0;
I < NumElements; ++
I) {
6671 int Elt = VSN->getMaskElt(
I);
6674 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6675 unsigned(Elt) % NumElements))
6678 return GS.getNode(DAG, SDLoc(VSN));
6693 assert(
Op.getSimpleValueType() == MVT::i64 &&
6694 "Expexted to convert i64 to f16.");
6706 assert(
Op.getSimpleValueType() == MVT::f16 &&
6707 "Expected to convert f16 to i64.");
6721 SDValue Op0 =
Op.getOperand(0);
6722 SDValue Op1 =
Op.getOperand(1);
6723 SDValue Op2 =
Op.getOperand(2);
6724 EVT VT =
Op.getValueType();
6729 if (VT == MVT::v2f64 &&
6753SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6757 SDValue Op0 =
Op.getOperand(0);
6758 SDValue Op1 =
Op.getOperand(1);
6759 EVT VT =
Op.getValueType();
6773 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6781SDValue SystemZTargetLowering::
6783 SDValue PackedOp =
Op.getOperand(0);
6784 EVT OutVT =
Op.getValueType();
6788 unsigned StartOffset = 0;
6795 ArrayRef<int> ShuffleMask = SVN->
getMask();
6800 if (ToBits == 64 && OutNumElts == 2) {
6801 int NumElem = ToBits / FromBits;
6802 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6808 int StartOffsetCandidate = -1;
6809 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6810 if (ShuffleMask[Elt] == -1)
6812 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6813 if (StartOffsetCandidate == -1)
6814 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6815 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6818 StartOffsetCandidate = -1;
6821 if (StartOffsetCandidate != -1) {
6822 StartOffset = StartOffsetCandidate;
6831 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6832 if (StartOffset >= OutNumElts) {
6833 Opcode = SystemZISD::UNPACK_LOW;
6834 StartOffset -= OutNumElts;
6836 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6837 }
while (FromBits != ToBits);
6842SDValue SystemZTargetLowering::
6844 SDValue PackedOp =
Op.getOperand(0);
6846 EVT OutVT =
Op.getValueType();
6850 unsigned NumInPerOut = InNumElts / OutNumElts;
6855 SmallVector<int, 16>
Mask(InNumElts);
6856 unsigned ZeroVecElt = InNumElts;
6857 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6858 unsigned MaskElt = PackedElt * NumInPerOut;
6859 unsigned End = MaskElt + NumInPerOut - 1;
6860 for (; MaskElt < End; MaskElt++)
6861 Mask[MaskElt] = ZeroVecElt++;
6862 Mask[MaskElt] = PackedElt;
6869 unsigned ByScalar)
const {
6871 SDValue Op0 =
Op.getOperand(0);
6872 SDValue Op1 =
Op.getOperand(1);
6874 EVT VT =
Op.getValueType();
6879 APInt SplatBits, SplatUndef;
6880 unsigned SplatBitSize;
6884 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6885 ElemBitSize,
true) &&
6886 SplatBitSize == ElemBitSize) {
6889 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6892 BitVector UndefElements;
6893 SDValue
Splat = BVN->getSplatValue(&UndefElements);
6898 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6905 if (VSN->isSplat()) {
6906 SDValue VSNOp0 = VSN->getOperand(0);
6907 unsigned Index = VSN->getSplatIndex();
6909 "Splat index should be defined and in first operand");
6916 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6934 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6935 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6936 SDValue Op0 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(0));
6937 SDValue Op1 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(1));
6938 if (ShiftAmt > 120) {
6942 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6946 SmallVector<int, 16>
Mask(16);
6947 for (
unsigned Elt = 0; Elt < 16; Elt++)
6948 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6950 if ((ShiftAmt & 7) == 0)
6954 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6972 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6973 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6974 SDValue Op0 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(0));
6975 SDValue Op1 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(1));
6976 if (ShiftAmt > 120) {
6980 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6984 SmallVector<int, 16>
Mask(16);
6985 for (
unsigned Elt = 0; Elt < 16; Elt++)
6986 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6988 if ((ShiftAmt & 7) == 0)
6992 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
7004 MVT DstVT =
Op.getSimpleValueType();
7007 unsigned SrcAS =
N->getSrcAddressSpace();
7009 assert(SrcAS !=
N->getDestAddressSpace() &&
7010 "addrspacecast must be between different address spaces");
7018 }
else if (DstVT == MVT::i32) {
7031 SDValue
In =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
7032 if (
In.getSimpleValueType() != MVT::f16)
7039 SDValue Chain,
bool IsStrict)
const {
7040 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7043 std::tie(Result, Chain) =
7052 bool IsStrict =
Op->isStrictFPOpcode();
7054 MVT VT =
Op.getSimpleValueType();
7055 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7063 if (!Subtarget.hasFPExtension() && !IsSigned)
7074 if (VT == MVT::i128) {
7077 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7087 bool IsStrict =
Op->isStrictFPOpcode();
7089 MVT VT =
Op.getSimpleValueType();
7090 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7091 SDValue Chain = IsStrict ?
Op.getOperand(0) : DAG.
getEntryNode();
7095 if (VT == MVT::f16) {
7102 if (!Subtarget.hasFPExtension() && !IsSigned)
7105 if (InVT == MVT::i128) {
7108 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7117 EVT RegVT =
Op.getValueType();
7118 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7125 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7127 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7128 AtomicLd->getMemOperand());
7131 assert(EVT(RegVT) == Ld->getMemoryVT() &&
"Unhandled f16 load");
7133 Ld->getBasePtr(), Ld->getPointerInfo(), MVT::i16,
7134 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
7148 Shft, AtomicSt->getBasePtr(),
7149 AtomicSt->getMemOperand());
7152 return DAG.
getTruncStore(St->getChain(),
DL, Shft, St->getBasePtr(), MVT::i16,
7153 St->getMemOperand());
7159 MVT ResultVT =
Op.getSimpleValueType();
7160 SDValue Arg =
Op.getOperand(0);
7161 unsigned Check =
Op.getConstantOperandVal(1);
7163 unsigned TDCMask = 0;
7186 SDValue Intr = DAG.
getNode(SystemZISD::TDC,
DL, ResultVT, Arg, TDCMaskV);
7193 SDValue Chain =
Op.getOperand(0);
7198 MachinePointerInfo MPI =
7202 SDValue StoreOps[] = {Chain,
StackPtr};
7204 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7208 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7213 switch (
Op.getOpcode()) {
7215 return lowerFRAMEADDR(
Op, DAG);
7217 return lowerRETURNADDR(
Op, DAG);
7219 return lowerBR_CC(
Op, DAG);
7221 return lowerSELECT_CC(
Op, DAG);
7223 return lowerSETCC(
Op, DAG);
7225 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7227 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7239 return lowerBITCAST(
Op, DAG);
7241 return lowerVASTART(
Op, DAG);
7243 return lowerVACOPY(
Op, DAG);
7245 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7247 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7249 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7251 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7253 return lowerSMUL_LOHI(
Op, DAG);
7255 return lowerUMUL_LOHI(
Op, DAG);
7257 return lowerSDIVREM(
Op, DAG);
7259 return lowerUDIVREM(
Op, DAG);
7264 return lowerXALUO(
Op, DAG);
7267 return lowerUADDSUBO_CARRY(
Op, DAG);
7269 return lowerOR(
Op, DAG);
7271 return lowerCTPOP(
Op, DAG);
7273 return lowerVECREDUCE_ADD(
Op, DAG);
7275 return lowerATOMIC_FENCE(
Op, DAG);
7277 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7279 return lowerATOMIC_STORE(
Op, DAG);
7281 return lowerATOMIC_LOAD(
Op, DAG);
7283 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7285 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7287 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7289 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7291 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7293 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7295 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7297 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7299 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7301 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7303 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7305 return lowerSTACKSAVE(
Op, DAG);
7307 return lowerSTACKRESTORE(
Op, DAG);
7309 return lowerPREFETCH(
Op, DAG);
7311 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7313 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7315 return lowerBUILD_VECTOR(
Op, DAG);
7317 return lowerVECTOR_SHUFFLE(
Op, DAG);
7319 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7321 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7323 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7325 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7327 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7329 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7331 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7333 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7337 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7339 return lowerFSHL(
Op, DAG);
7341 return lowerFSHR(
Op, DAG);
7344 return lowerFP_EXTEND(
Op, DAG);
7349 return lower_FP_TO_INT(
Op, DAG);
7354 return lower_INT_TO_FP(
Op, DAG);
7356 return lowerLoadF16(
Op, DAG);
7358 return lowerStoreF16(
Op, DAG);
7360 return lowerIS_FPCLASS(
Op, DAG);
7362 return lowerGET_ROUNDING(
Op, DAG);
7364 return lowerREADCYCLECOUNTER(
Op, DAG);
7386 &SystemZ::FP128BitRegClass);
7395 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7410 &SystemZ::FP128BitRegClass);
7427 switch (
N->getOpcode()) {
7431 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7434 DL, Tys,
Ops, MVT::i128, MMO);
7437 if (
N->getValueType(0) == MVT::f128)
7451 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7454 DL, Tys,
Ops, MVT::i128, MMO);
7460 MVT::Other, Res), 0);
7472 DL, Tys,
Ops, MVT::i128, MMO);
7486 EVT SrcVT = Src.getValueType();
7487 EVT ResVT =
N->getValueType(0);
7488 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7490 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7491 if (Subtarget.hasVector()) {
7499 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7501 Subtarget.hasVector()
7515 bool IsStrict =
N->isStrictFPOpcode();
7517 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7518 EVT ResVT =
N->getValueType(0);
7520 if (ResVT == MVT::f16) {
7543 bool IsStrict =
N->isStrictFPOpcode();
7545 EVT ResVT =
N->getValueType(0);
7546 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7549 if (InVT == MVT::f16) {
7555 std::tie(InF32, Chain) =
7580bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7581 if (!Subtarget.hasVector())
7595 DAGCombinerInfo &DCI,
7603 unsigned Opcode =
Op.getOpcode();
7606 Op =
Op.getOperand(0);
7608 canTreatAsByteVector(
Op.getValueType())) {
7617 BytesPerElement,
First))
7624 if (Byte % BytesPerElement != 0)
7627 Index = Byte / BytesPerElement;
7631 canTreatAsByteVector(
Op.getValueType())) {
7634 EVT OpVT =
Op.getValueType();
7636 if (OpBytesPerElement < BytesPerElement)
7640 unsigned End = (
Index + 1) * BytesPerElement;
7641 if (End % OpBytesPerElement != 0)
7644 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7648 if (!
Op.getValueType().isInteger()) {
7653 DCI.AddToWorklist(
Op.getNode());
7656 if (ResIntVT != ResVT) {
7657 DCI.AddToWorklist(
Op.getNode());
7664 canTreatAsByteVector(
Op.getValueType()) &&
7665 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7667 EVT ExtVT =
Op.getValueType();
7668 EVT OpVT =
Op.getOperand(0).getValueType();
7671 unsigned Byte =
Index * BytesPerElement;
7672 unsigned SubByte =
Byte % ExtBytesPerElement;
7673 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7674 if (SubByte < MinSubByte ||
7675 SubByte + BytesPerElement > ExtBytesPerElement)
7678 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7680 Byte += SubByte - MinSubByte;
7681 if (Byte % BytesPerElement != 0)
7683 Op =
Op.getOperand(0);
7690 if (
Op.getValueType() != VecVT) {
7692 DCI.AddToWorklist(
Op.getNode());
7702SDValue SystemZTargetLowering::combineTruncateExtract(
7709 SDValue Vec =
Op.getOperand(0);
7711 if (canTreatAsByteVector(VecVT)) {
7715 if (BytesPerElement % TruncBytes == 0) {
7721 unsigned Scale = BytesPerElement / TruncBytes;
7722 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7729 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7730 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7738SDValue SystemZTargetLowering::combineZERO_EXTEND(
7739 SDNode *
N, DAGCombinerInfo &DCI)
const {
7741 SelectionDAG &DAG = DCI.DAG;
7742 SDValue N0 =
N->getOperand(0);
7743 EVT VT =
N->getValueType(0);
7744 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7747 if (TrueOp && FalseOp) {
7752 SDValue NewSelect = DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, VT,
Ops);
7755 SDValue TruncSelect =
7757 DCI.CombineTo(N0.
getNode(), TruncSelect);
7800 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7818SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7819 SDNode *
N, DAGCombinerInfo &DCI)
const {
7823 SelectionDAG &DAG = DCI.DAG;
7825 EVT VT =
N->getValueType(0);
7839SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7840 SDNode *
N, DAGCombinerInfo &DCI)
const {
7844 SelectionDAG &DAG = DCI.DAG;
7846 EVT VT =
N->getValueType(0);
7853 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7854 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7870SDValue SystemZTargetLowering::combineMERGE(
7871 SDNode *
N, DAGCombinerInfo &DCI)
const {
7872 SelectionDAG &DAG = DCI.DAG;
7873 unsigned Opcode =
N->getOpcode();
7881 if (Op1 ==
N->getOperand(0))
7886 if (ElemBytes <= 4) {
7887 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7888 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7894 DCI.AddToWorklist(Op1.
getNode());
7896 SDValue
Op = DAG.
getNode(Opcode, SDLoc(
N), OutVT, Op1);
7897 DCI.AddToWorklist(
Op.getNode());
7906 LoPart = HiPart =
nullptr;
7911 if (
Use.getResNo() != 0)
7916 bool IsLoPart =
true;
7941 LoPart = HiPart =
nullptr;
7946 if (
Use.getResNo() != 0)
7952 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7955 switch (
User->getConstantOperandVal(1)) {
7956 case SystemZ::subreg_l64:
7961 case SystemZ::subreg_h64:
7973SDValue SystemZTargetLowering::combineLOAD(
7974 SDNode *
N, DAGCombinerInfo &DCI)
const {
7975 SelectionDAG &DAG = DCI.DAG;
7976 EVT LdVT =
N->getValueType(0);
7980 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7981 if (PtrVT != LoadNodeVT) {
7985 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7986 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7987 LN->getMemOperand());
7997 SDNode *LoPart, *HiPart;
8003 SDValue EltLoad = DAG.
getLoad(
8005 LD->getPointerInfo(),
LD->getBaseAlign(),
8006 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8008 DCI.CombineTo(HiPart, EltLoad,
true);
8012 SDValue EltLoad = DAG.
getLoad(
8015 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
8016 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8018 DCI.CombineTo(LoPart, EltLoad,
true);
8025 DCI.AddToWorklist(Chain.
getNode());
8026 return SDValue(
N, 0);
8040 for (SDUse &Use :
N->uses()) {
8041 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8044 Replicate = SDValue(
Use.getUser(), 0);
8045 }
else if (
Use.getResNo() == 0)
8048 if (!Replicate || OtherUses.
empty())
8054 for (SDNode *U : OtherUses) {
8056 for (SDValue
Op :
U->ops())
8057 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8060 return SDValue(
N, 0);
8063bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8064 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8066 if (Subtarget.hasVectorEnhancements2())
8067 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8079 for (
unsigned i = 0; i < NumElts; ++i) {
8080 if (M[i] < 0)
continue;
8081 if ((
unsigned) M[i] != NumElts - 1 - i)
8089 for (
auto *U : StoredVal->
users()) {
8091 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8150SDValue SystemZTargetLowering::combineSTORE(
8151 SDNode *
N, DAGCombinerInfo &DCI)
const {
8152 SelectionDAG &DAG = DCI.DAG;
8155 EVT MemVT = SN->getMemoryVT();
8159 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8160 if (PtrVT != StoreNodeVT) {
8164 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8165 SN->getPointerInfo(), SN->getBaseAlign(),
8166 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8174 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8176 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8177 DCI.AddToWorklist(
Value.getNode());
8181 SN->getBasePtr(), SN->getMemoryVT(),
8182 SN->getMemOperand());
8193 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8197 if (!SN->isTruncatingStore() &&
8213 Ops, MemVT, SN->getMemOperand());
8216 if (!SN->isTruncatingStore() &&
8219 Subtarget.hasVectorEnhancements2()) {
8221 ArrayRef<int> ShuffleMask = SVN->
getMask();
8229 Ops, MemVT, SN->getMemOperand());
8234 if (!SN->isTruncatingStore() &&
8237 N->getOperand(0).reachesChainWithoutSideEffects(SDValue(Op1.
getNode(), 1))) {
8241 Ops, MemVT, SN->getMemOperand());
8246 SDValue LoPart, HiPart;
8251 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8252 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8254 SN->getChain(),
DL, LoPart,
8256 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8257 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8270 SDValue
Word = SDValue();
8275 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8277 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8281 APInt Val =
C->getAPIntValue();
8284 assert(SN->isTruncatingStore() &&
8285 "Non-truncating store and immediate value does not fit?");
8286 Val = Val.
trunc(TotBytes * 8);
8289 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8290 if (VCI.isVectorConstantLegal(Subtarget) &&
8291 VCI.Opcode == SystemZISD::REPLICATE) {
8299 auto FindReplicatedReg = [&](SDValue MulOp) {
8300 EVT MulVT = MulOp.getValueType();
8301 if (MulOp->getOpcode() ==
ISD::MUL &&
8302 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8304 SDValue
LHS = MulOp->getOperand(0);
8306 WordVT =
LHS->getOperand(0).getValueType();
8313 SystemZVectorConstantInfo VCI(
8315 if (VCI.isVectorConstantLegal(Subtarget) &&
8316 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8317 WordVT == VCI.VecVT.getScalarType())
8329 FindReplicatedReg(SplatVal);
8334 FindReplicatedReg(Op1);
8337 if (Word != SDValue()) {
8339 "Bad type handling");
8343 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8344 SN->getBasePtr(), SN->getMemOperand());
8351SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8352 SDNode *
N, DAGCombinerInfo &DCI)
const {
8353 SelectionDAG &DAG = DCI.DAG;
8356 N->getOperand(0).hasOneUse() &&
8357 Subtarget.hasVectorEnhancements2()) {
8359 ArrayRef<int> ShuffleMask = SVN->
getMask();
8361 SDValue
Load =
N->getOperand(0);
8372 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8376 DCI.CombineTo(
N, ESLoad);
8380 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8383 return SDValue(
N, 0);
8390SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8391 SDNode *
N, DAGCombinerInfo &DCI)
const {
8392 SelectionDAG &DAG = DCI.DAG;
8394 if (!Subtarget.hasVector())
8398 SDValue
Op =
N->getOperand(0);
8400 Op.getValueType().isVector() &&
8401 Op.getOperand(0).getValueType().isVector() &&
8402 Op.getValueType().getVectorNumElements() ==
8403 Op.getOperand(0).getValueType().getVectorNumElements())
8404 Op =
Op.getOperand(0);
8408 EVT VecVT =
Op.getValueType();
8411 Op.getOperand(0),
N->getOperand(1));
8412 DCI.AddToWorklist(
Op.getNode());
8414 if (EltVT !=
N->getValueType(0)) {
8415 DCI.AddToWorklist(
Op.getNode());
8425 if (canTreatAsByteVector(VecVT))
8426 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8427 IndexN->getZExtValue(), DCI,
false);
8432SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8433 SDNode *
N, DAGCombinerInfo &DCI)
const {
8434 SelectionDAG &DAG = DCI.DAG;
8436 if (
N->getOperand(0) ==
N->getOperand(1))
8437 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8447 if (Chain1 == Chain2)
8455SDValue SystemZTargetLowering::combineFP_ROUND(
8456 SDNode *
N, DAGCombinerInfo &DCI)
const {
8458 if (!Subtarget.hasVector())
8467 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8468 SelectionDAG &DAG = DCI.DAG;
8470 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8476 for (
auto *U : Vec->
users()) {
8477 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8479 U->getOperand(0) == Vec &&
8481 U->getConstantOperandVal(1) == 1) {
8482 SDValue OtherRound = SDValue(*
U->user_begin(), 0);
8483 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8484 OtherRound.
getOperand(OpNo) == SDValue(U, 0) &&
8486 SDValue VRound, Chain;
8487 if (
N->isStrictFPOpcode()) {
8491 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8492 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8495 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8497 DCI.AddToWorklist(VRound.
getNode());
8501 DCI.AddToWorklist(Extract1.
getNode());
8507 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8510 N->getVTList(), Extract0, Chain);
8519SDValue SystemZTargetLowering::combineFP_EXTEND(
8520 SDNode *
N, DAGCombinerInfo &DCI)
const {
8522 if (!Subtarget.hasVector())
8531 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8532 SelectionDAG &DAG = DCI.DAG;
8534 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8540 for (
auto *U : Vec->
users()) {
8541 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8543 U->getOperand(0) == Vec &&
8545 U->getConstantOperandVal(1) == 2) {
8546 SDValue OtherExtend = SDValue(*
U->user_begin(), 0);
8547 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8548 OtherExtend.
getOperand(OpNo) == SDValue(U, 0) &&
8550 SDValue VExtend, Chain;
8551 if (
N->isStrictFPOpcode()) {
8555 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8556 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8559 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8561 DCI.AddToWorklist(VExtend.
getNode());
8565 DCI.AddToWorklist(Extract1.
getNode());
8571 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8574 N->getVTList(), Extract0, Chain);
8583SDValue SystemZTargetLowering::combineINT_TO_FP(
8584 SDNode *
N, DAGCombinerInfo &DCI)
const {
8587 SelectionDAG &DAG = DCI.DAG;
8589 unsigned Opcode =
N->getOpcode();
8590 EVT OutVT =
N->getValueType(0);
8592 SDValue
Op =
N->getOperand(0);
8594 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8600 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8601 OutScalarBits <= 64) {
8605 unsigned ExtOpcode =
8607 SDValue ExtOp = DAG.
getNode(ExtOpcode, SDLoc(
N), ExtVT,
Op);
8608 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8613SDValue SystemZTargetLowering::combineFCOPYSIGN(
8614 SDNode *
N, DAGCombinerInfo &DCI)
const {
8615 SelectionDAG &DAG = DCI.DAG;
8616 EVT VT =
N->getValueType(0);
8617 SDValue ValOp =
N->getOperand(0);
8618 SDValue SignOp =
N->getOperand(1);
8629SDValue SystemZTargetLowering::combineBSWAP(
8630 SDNode *
N, DAGCombinerInfo &DCI)
const {
8631 SelectionDAG &DAG = DCI.DAG;
8634 N->getOperand(0).hasOneUse() &&
8635 canLoadStoreByteSwapped(
N->getValueType(0))) {
8636 SDValue
Load =
N->getOperand(0);
8644 EVT LoadVT =
N->getValueType(0);
8645 if (LoadVT == MVT::i16)
8650 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8653 SDValue ResVal = BSLoad;
8654 if (
N->getValueType(0) == MVT::i16)
8659 DCI.CombineTo(
N, ResVal);
8663 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8666 return SDValue(
N, 0);
8670 SDValue
Op =
N->getOperand(0);
8672 Op.getValueType().isVector() &&
8673 Op.getOperand(0).getValueType().isVector() &&
8674 Op.getValueType().getVectorNumElements() ==
8675 Op.getOperand(0).getValueType().getVectorNumElements())
8676 Op =
Op.getOperand(0);
8680 SDValue Vec =
Op.getOperand(0);
8681 SDValue Elt =
Op.getOperand(1);
8682 SDValue
Idx =
Op.getOperand(2);
8688 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8690 EVT VecVT =
N->getValueType(0);
8694 DCI.AddToWorklist(Vec.
getNode());
8698 DCI.AddToWorklist(Elt.
getNode());
8701 DCI.AddToWorklist(Vec.
getNode());
8703 DCI.AddToWorklist(Elt.
getNode());
8711 if (SV &&
Op.hasOneUse()) {
8712 SDValue Op0 =
Op.getOperand(0);
8713 SDValue Op1 =
Op.getOperand(1);
8719 EVT VecVT =
N->getValueType(0);
8722 DCI.AddToWorklist(Op0.
getNode());
8726 DCI.AddToWorklist(Op1.
getNode());
8729 DCI.AddToWorklist(Op0.
getNode());
8731 DCI.AddToWorklist(Op1.
getNode());
8739SDValue SystemZTargetLowering::combineSETCC(
8740 SDNode *
N, DAGCombinerInfo &DCI)
const {
8741 SelectionDAG &DAG = DCI.DAG;
8743 const SDValue
LHS =
N->getOperand(0);
8744 const SDValue
RHS =
N->getOperand(1);
8747 EVT VT =
N->getValueType(0);
8757 Src.getValueType().isFixedLengthVector() &&
8758 Src.getValueType().getScalarType() == MVT::i1) {
8759 EVT CmpVT = Src.getOperand(0).getValueType();
8776 unsigned Depth = 0) {
8784 case SystemZISD::IPM:
8789 case SystemZISD::SELECT_CCMASK: {
8791 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8792 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8795 return std::make_pair(OpCC, OpCCValid);
8800 int CCValidVal = CCValid->getZExtValue();
8801 return std::make_pair(Op4CCReg, CCValidVal);
8812 return std::make_pair(Op0CC, Op0CCValid);
8828 return {Val, Val, Val, Val};
8829 case SystemZISD::IPM: {
8834 for (
auto CC : {0, 1, 2, 3})
8837 return ShiftedCCVals;
8839 case SystemZISD::SELECT_CCMASK: {
8843 if (!CCValid || !CCMask)
8846 int CCValidVal = CCValid->getZExtValue();
8847 int CCMaskVal = CCMask->getZExtValue();
8857 if (TrueSDVals.empty() || FalseSDVals.empty())
8860 for (
auto &CCVal : {0, 1, 2, 3})
8861 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8863 : FalseSDVals[CCVal]);
8864 return MergedSDVals;
8881 if (Op0SDVals.empty() || Op1SDVals.empty())
8884 for (
auto CCVal : {0, 1, 2, 3})
8886 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8887 return BinaryOpSDVals;
8898 auto *CCNode = CCReg.
getNode();
8902 if (CCNode->getOpcode() == SystemZISD::TM) {
8905 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8908 if (!Op0Node || !Op1Node)
8910 auto Op0APVal = Op0Node->getAPIntValue();
8911 auto Op1APVal = Op1Node->getAPIntValue();
8912 auto Result = Op0APVal & Op1APVal;
8913 bool AllOnes = Result == Op1APVal;
8914 bool AllZeros = Result == 0;
8915 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8916 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8920 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8925 if (Op0SDVals.empty() || Op1SDVals.empty())
8928 for (
auto CC : {0, 1, 2, 3}) {
8929 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8933 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8935 NewCCMask &= Op0CCValid;
8938 CCValid = Op0CCValid;
8941 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8948 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8952 if (Op0SDVals.empty() || Op1SDVals.empty())
8956 auto CmpTypeVal = CmpType->getZExtValue();
8957 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8961 if (!Op0Node || !Op1Node)
8963 auto Op0APVal = Op0Node->getAPIntValue();
8964 auto Op1APVal = Op1Node->getAPIntValue();
8966 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8967 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8970 for (
auto CC : {0, 1, 2, 3}) {
8971 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8975 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8977 NewCCMask &= Op0CCValid;
8980 CCValid = Op0CCValid;
8993 const auto isFlagOutOpCC = [](
const Value *V) {
8995 const Value *RHSVal;
9002 if (CB->isInlineAsm()) {
9004 return IA && IA->getConstraintString().contains(
"{@cc}");
9015 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
9018 return {-1, -1, -1};
9022 DAGCombinerInfo &DCI)
const {
9028 if (!CCValid || !CCMask)
9031 int CCValidVal = CCValid->getZExtValue();
9032 int CCMaskVal = CCMask->getZExtValue();
9039 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9040 CCMaskVal != CCValidVal)
9041 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9045 N->getOperand(3), CCReg);
9049SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9050 SDNode *
N, DAGCombinerInfo &DCI)
const {
9056 if (!CCValid || !CCMask)
9059 int CCValidVal = CCValid->getZExtValue();
9060 int CCMaskVal = CCMask->getZExtValue();
9063 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9067 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9068 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9070 if (Val.getOperand(4) != CCReg)
9077 int CCMaskVal = CCMask->getZExtValue();
9078 for (
auto &CC : {0, 1, 2, 3})
9079 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9087 SDValue
TrueVal =
N->getOperand(0);
9093 if (TrueSDVals.empty())
9094 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9095 if (FalseSDVals.empty())
9096 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9097 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9098 SmallSet<SDValue, 4> MergedSDValsSet;
9100 for (
auto CC : {0, 1, 2, 3}) {
9101 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9102 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9106 if (MergedSDValsSet.
size() == 1)
9107 return *MergedSDValsSet.
begin();
9108 if (MergedSDValsSet.
size() == 2) {
9109 auto BeginIt = MergedSDValsSet.
begin();
9110 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9111 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9114 for (
auto CC : {0, 1, 2, 3}) {
9116 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9117 ? (TrueSDVals[CC] == NewTrueVal)
9118 : (FalseSDVals[CC] == NewTrueVal);
9120 CCMaskVal = NewCCMask;
9121 CCMaskVal &= CCValidVal;
9124 IsCombinedCCReg =
true;
9132 if (CCMaskVal == CCValidVal)
9135 if (IsCombinedCCReg)
9137 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9144SDValue SystemZTargetLowering::combineGET_CCMASK(
9145 SDNode *
N, DAGCombinerInfo &DCI)
const {
9150 if (!CCValid || !CCMask)
9152 int CCValidVal = CCValid->getZExtValue();
9153 int CCMaskVal = CCMask->getZExtValue();
9155 SDValue
Select =
N->getOperand(0);
9158 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9163 if (!SelectCCValid || !SelectCCMask)
9165 int SelectCCValidVal = SelectCCValid->getZExtValue();
9166 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9170 if (!TrueVal || !FalseVal)
9174 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9175 SelectCCMaskVal ^= SelectCCValidVal;
9179 if (SelectCCValidVal & ~CCValidVal)
9181 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9184 return Select->getOperand(4);
9187SDValue SystemZTargetLowering::combineIntDIVREM(
9188 SDNode *
N, DAGCombinerInfo &DCI)
const {
9189 SelectionDAG &DAG = DCI.DAG;
9190 EVT VT =
N->getValueType(0);
9207SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9208 SDNode *
N, DAGCombinerInfo &DCI)
const {
9209 SelectionDAG &DAG = DCI.DAG;
9213 "SRL or SRA node is required here!");
9215 if (!Subtarget.hasVector())
9225 SDValue ShiftOperand =
N->getOperand(0);
9245 if (!IsSignExt && !IsZeroExt)
9251 SDValue MulhRightOp;
9253 unsigned ActiveBits = IsSignExt
9254 ?
Constant->getAPIntValue().getSignificantBits()
9255 :
Constant->getAPIntValue().getActiveBits();
9256 if (ActiveBits > NarrowVTSize)
9272 unsigned ActiveBits = IsSignExt
9273 ?
Constant->getAPIntValue().getSignificantBits()
9274 :
Constant->getAPIntValue().getActiveBits();
9275 if (ActiveBits > NarrowVTSize)
9292 "Cannot have a multiply node with two different operand types.");
9294 "Cannot have an add node with two different operand types.");
9305 if (ShiftAmt != NarrowVTSize)
9309 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9310 NarrowVT == MVT::v4i32 ||
9311 (Subtarget.hasVectorEnhancements3() &&
9312 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9316 SDValue
Result = DAG.
getNode(IsSignExt ? SystemZISD::VMAH : SystemZISD::VMALH,
9318 MulhRightOp, MulhAddOp);
9319 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9330 EVT VT =
Op.getValueType();
9339 Op =
Op.getOperand(0);
9340 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9344 bool CanUseEven =
true, CanUseOdd =
true;
9345 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9346 if (ShuffleMask[Elt] == -1)
9348 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9350 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9353 Op =
Op.getOperand(0);
9355 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9357 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9363 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9367 Op =
Op.getOperand(0);
9369 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9371 unsigned Elem =
Op.getConstantOperandVal(1);
9372 Op =
Op.getOperand(0);
9374 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9376 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9383SDValue SystemZTargetLowering::combineMUL(
9384 SDNode *
N, DAGCombinerInfo &DCI)
const {
9385 SelectionDAG &DAG = DCI.DAG;
9392 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9393 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9398SDValue SystemZTargetLowering::combineINTRINSIC(
9399 SDNode *
N, DAGCombinerInfo &DCI)
const {
9400 SelectionDAG &DAG = DCI.DAG;
9402 unsigned Id =
N->getConstantOperandVal(1);
9406 case Intrinsic::s390_vll:
9407 case Intrinsic::s390_vlrl:
9409 if (
C->getZExtValue() >= 15)
9410 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9411 N->getOperand(3), MachinePointerInfo());
9414 case Intrinsic::s390_vstl:
9415 case Intrinsic::s390_vstrl:
9417 if (
C->getZExtValue() >= 15)
9418 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9419 N->getOperand(4), MachinePointerInfo());
9427 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9434 switch(
N->getOpcode()) {
9439 case SystemZISD::MERGE_HIGH:
9440 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9445 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9455 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9456 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9459 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9460 case ISD::MUL:
return combineMUL(
N, DCI);
9464 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9476 EVT VT =
Op.getValueType();
9479 unsigned Opcode =
Op.getOpcode();
9481 unsigned Id =
Op.getConstantOperandVal(0);
9483 case Intrinsic::s390_vpksh:
9484 case Intrinsic::s390_vpksf:
9485 case Intrinsic::s390_vpksg:
9486 case Intrinsic::s390_vpkshs:
9487 case Intrinsic::s390_vpksfs:
9488 case Intrinsic::s390_vpksgs:
9489 case Intrinsic::s390_vpklsh:
9490 case Intrinsic::s390_vpklsf:
9491 case Intrinsic::s390_vpklsg:
9492 case Intrinsic::s390_vpklshs:
9493 case Intrinsic::s390_vpklsfs:
9494 case Intrinsic::s390_vpklsgs:
9496 SrcDemE = DemandedElts;
9499 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9502 case Intrinsic::s390_vuphb:
9503 case Intrinsic::s390_vuphh:
9504 case Intrinsic::s390_vuphf:
9505 case Intrinsic::s390_vuplhb:
9506 case Intrinsic::s390_vuplhh:
9507 case Intrinsic::s390_vuplhf:
9508 SrcDemE =
APInt(NumElts * 2, 0);
9511 case Intrinsic::s390_vuplb:
9512 case Intrinsic::s390_vuplhw:
9513 case Intrinsic::s390_vuplf:
9514 case Intrinsic::s390_vupllb:
9515 case Intrinsic::s390_vupllh:
9516 case Intrinsic::s390_vupllf:
9517 SrcDemE =
APInt(NumElts * 2, 0);
9520 case Intrinsic::s390_vpdi: {
9522 SrcDemE =
APInt(NumElts, 0);
9523 if (!DemandedElts[OpNo - 1])
9525 unsigned Mask =
Op.getConstantOperandVal(3);
9526 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9528 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9531 case Intrinsic::s390_vsldb: {
9533 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9534 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9535 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9536 unsigned NumSrc0Els = 16 - FirstIdx;
9537 SrcDemE =
APInt(NumElts, 0);
9539 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9542 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9547 case Intrinsic::s390_vperm:
9556 case SystemZISD::JOIN_DWORDS:
9558 SrcDemE =
APInt(1, 1);
9560 case SystemZISD::SELECT_CCMASK:
9561 SrcDemE = DemandedElts;
9572 const APInt &DemandedElts,
9587 const APInt &DemandedElts,
9589 unsigned Depth)
const {
9593 unsigned Tmp0, Tmp1;
9595 Known.Zero.setBitsFrom(2);
9598 EVT VT =
Op.getValueType();
9599 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9602 "KnownBits does not match VT in bitwidth");
9605 "DemandedElts does not match VT number of elements");
9607 unsigned Opcode =
Op.getOpcode();
9609 bool IsLogical =
false;
9610 unsigned Id =
Op.getConstantOperandVal(0);
9612 case Intrinsic::s390_vpksh:
9613 case Intrinsic::s390_vpksf:
9614 case Intrinsic::s390_vpksg:
9615 case Intrinsic::s390_vpkshs:
9616 case Intrinsic::s390_vpksfs:
9617 case Intrinsic::s390_vpksgs:
9618 case Intrinsic::s390_vpklsh:
9619 case Intrinsic::s390_vpklsf:
9620 case Intrinsic::s390_vpklsg:
9621 case Intrinsic::s390_vpklshs:
9622 case Intrinsic::s390_vpklsfs:
9623 case Intrinsic::s390_vpklsgs:
9624 case Intrinsic::s390_vpdi:
9625 case Intrinsic::s390_vsldb:
9626 case Intrinsic::s390_vperm:
9629 case Intrinsic::s390_vuplhb:
9630 case Intrinsic::s390_vuplhh:
9631 case Intrinsic::s390_vuplhf:
9632 case Intrinsic::s390_vupllb:
9633 case Intrinsic::s390_vupllh:
9634 case Intrinsic::s390_vupllf:
9637 case Intrinsic::s390_vuphb:
9638 case Intrinsic::s390_vuphh:
9639 case Intrinsic::s390_vuphf:
9640 case Intrinsic::s390_vuplb:
9641 case Intrinsic::s390_vuplhw:
9642 case Intrinsic::s390_vuplf: {
9657 case SystemZISD::JOIN_DWORDS:
9658 case SystemZISD::SELECT_CCMASK:
9661 case SystemZISD::REPLICATE: {
9684 if (
LHS == 1)
return 1;
9687 if (
RHS == 1)
return 1;
9688 unsigned Common = std::min(
LHS,
RHS);
9689 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9690 EVT VT =
Op.getValueType();
9692 if (SrcBitWidth > VTBits) {
9693 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9694 if (Common > SrcExtraBits)
9695 return (Common - SrcExtraBits);
9698 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9705 unsigned Depth)
const {
9706 if (
Op.getResNo() != 0)
9708 unsigned Opcode =
Op.getOpcode();
9710 unsigned Id =
Op.getConstantOperandVal(0);
9712 case Intrinsic::s390_vpksh:
9713 case Intrinsic::s390_vpksf:
9714 case Intrinsic::s390_vpksg:
9715 case Intrinsic::s390_vpkshs:
9716 case Intrinsic::s390_vpksfs:
9717 case Intrinsic::s390_vpksgs:
9718 case Intrinsic::s390_vpklsh:
9719 case Intrinsic::s390_vpklsf:
9720 case Intrinsic::s390_vpklsg:
9721 case Intrinsic::s390_vpklshs:
9722 case Intrinsic::s390_vpklsfs:
9723 case Intrinsic::s390_vpklsgs:
9724 case Intrinsic::s390_vpdi:
9725 case Intrinsic::s390_vsldb:
9726 case Intrinsic::s390_vperm:
9728 case Intrinsic::s390_vuphb:
9729 case Intrinsic::s390_vuphh:
9730 case Intrinsic::s390_vuphf:
9731 case Intrinsic::s390_vuplb:
9732 case Intrinsic::s390_vuplhw:
9733 case Intrinsic::s390_vuplf: {
9737 EVT VT =
Op.getValueType();
9747 case SystemZISD::SELECT_CCMASK:
9760 switch (
Op->getOpcode()) {
9761 case SystemZISD::PCREL_WRAPPER:
9762 case SystemZISD::PCREL_OFFSET:
9773 "Unexpected stack alignment");
9776 unsigned StackProbeSize =
9779 StackProbeSize &= ~(StackAlign - 1);
9780 return StackProbeSize ? StackProbeSize : StackAlign;
9819 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9821 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9827 if (miI ==
MBB->end()) {
9829 if (Succ->isLiveIn(SystemZ::CC))
9840 switch (
MI.getOpcode()) {
9841 case SystemZ::Select32:
9842 case SystemZ::Select64:
9843 case SystemZ::Select128:
9844 case SystemZ::SelectF32:
9845 case SystemZ::SelectF64:
9846 case SystemZ::SelectF128:
9847 case SystemZ::SelectVR32:
9848 case SystemZ::SelectVR64:
9849 case SystemZ::SelectVR128:
9881 for (
auto *
MI : Selects) {
9882 Register DestReg =
MI->getOperand(0).getReg();
9883 Register TrueReg =
MI->getOperand(1).getReg();
9884 Register FalseReg =
MI->getOperand(2).getReg();
9889 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9892 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9893 TrueReg = It->second.first;
9895 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9896 FalseReg = It->second.second;
9899 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9904 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9915 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9916 assert(TFL->hasReservedCallFrame(MF) &&
9917 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9922 uint32_t NumBytes =
MI.getOperand(0).getImm();
9927 MI.eraseFromParent();
9936 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9938 unsigned CCValid =
MI.getOperand(3).getImm();
9939 unsigned CCMask =
MI.getOperand(4).getImm();
9944 SmallVector<MachineInstr*, 8> Selects;
9945 SmallVector<MachineInstr*, 8> DbgValues;
9951 assert(NextMI.getOperand(3).getImm() == CCValid &&
9952 "Bad CCValid operands since CC was not redefined.");
9953 if (NextMI.getOperand(4).getImm() == CCMask ||
9954 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9960 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9961 NextMI.usesCustomInsertionHook())
9964 for (
auto *SelMI : Selects)
9965 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9969 if (NextMI.isDebugInstr()) {
9971 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9974 }
else if (User || ++
Count > 20)
9978 MachineInstr *LastMI = Selects.back();
9979 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9981 MachineBasicBlock *StartMBB =
MBB;
10011 for (
auto *SelMI : Selects)
10012 SelMI->eraseFromParent();
10015 for (
auto *DbgMI : DbgValues)
10016 MBB->
splice(InsertPos, StartMBB, DbgMI);
10027 unsigned StoreOpcode,
10028 unsigned STOCOpcode,
10029 bool Invert)
const {
10030 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10032 Register SrcReg =
MI.getOperand(0).getReg();
10033 MachineOperand
Base =
MI.getOperand(1);
10034 int64_t Disp =
MI.getOperand(2).getImm();
10035 Register IndexReg =
MI.getOperand(3).getReg();
10036 unsigned CCValid =
MI.getOperand(4).getImm();
10037 unsigned CCMask =
MI.getOperand(5).getImm();
10040 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10044 MachineMemOperand *MMO =
nullptr;
10045 for (
auto *
I :
MI.memoperands())
10046 if (
I->isStore()) {
10054 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10066 MI.eraseFromParent();
10074 MachineBasicBlock *StartMBB =
MBB;
10080 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10107 MI.eraseFromParent();
10117 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10125 MachineBasicBlock *StartMBB =
MBB;
10143 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10170 MI.eraseFromParent();
10181 bool Invert)
const {
10183 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10190 int64_t Disp =
MI.getOperand(2).getImm();
10192 Register BitShift =
MI.getOperand(4).getReg();
10193 Register NegBitShift =
MI.getOperand(5).getReg();
10194 unsigned BitSize =
MI.getOperand(6).getImm();
10198 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10199 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10200 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10210 MachineBasicBlock *StartMBB =
MBB;
10246 .
addImm(-1U << (32 - BitSize))
10248 }
else if (BinOpcode)
10276 MI.eraseFromParent();
10287 unsigned KeepOldMask)
const {
10289 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10295 int64_t Disp =
MI.getOperand(2).getImm();
10297 Register BitShift =
MI.getOperand(4).getReg();
10298 Register NegBitShift =
MI.getOperand(5).getReg();
10299 unsigned BitSize =
MI.getOperand(6).getImm();
10303 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10304 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10305 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10316 MachineBasicBlock *StartMBB =
MBB;
10384 MI.eraseFromParent();
10394 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10400 int64_t Disp =
MI.getOperand(2).getImm();
10401 Register CmpVal =
MI.getOperand(3).getReg();
10402 Register OrigSwapVal =
MI.getOperand(4).getReg();
10403 Register BitShift =
MI.getOperand(5).getReg();
10404 Register NegBitShift =
MI.getOperand(6).getReg();
10405 int64_t BitSize =
MI.getOperand(7).getImm();
10411 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10412 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10413 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10414 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10426 MachineBasicBlock *StartMBB =
MBB;
10503 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10506 MI.eraseFromParent();
10514 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10519 .
add(
MI.getOperand(1))
10520 .
addImm(SystemZ::subreg_h64)
10521 .
add(
MI.getOperand(2))
10522 .
addImm(SystemZ::subreg_l64);
10523 MI.eraseFromParent();
10532 bool ClearEven)
const {
10534 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10556 MI.eraseFromParent();
10563 unsigned Opcode,
bool IsMemset)
const {
10565 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10570 uint64_t DestDisp =
MI.getOperand(1).getImm();
10575 auto foldDisplIfNeeded = [&](MachineOperand &
Base,
uint64_t &Disp) ->
void {
10578 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10588 SrcDisp =
MI.getOperand(3).getImm();
10590 SrcBase = DestBase;
10591 SrcDisp = DestDisp++;
10592 foldDisplIfNeeded(DestBase, DestDisp);
10595 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10596 bool IsImmForm = LengthMO.
isImm();
10597 bool IsRegForm = !IsImmForm;
10600 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10602 MachineOperand DBase,
uint64_t DDisp,
10604 unsigned Length) ->
void {
10608 if (ByteMO.
isImm())
10623 bool NeedsLoop =
false;
10625 Register LenAdjReg = SystemZ::NoRegister;
10627 ImmLength = LengthMO.
getImm();
10628 ImmLength += IsMemset ? 2 : 1;
10629 if (ImmLength == 0) {
10630 MI.eraseFromParent();
10633 if (Opcode == SystemZ::CLC) {
10634 if (ImmLength > 3 * 256)
10644 }
else if (ImmLength > 6 * 256)
10652 LenAdjReg = LengthMO.
getReg();
10657 MachineBasicBlock *EndMBB =
10658 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10666 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10676 auto loadZeroAddress = [&]() -> MachineOperand {
10681 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10682 DestBase = loadZeroAddress();
10683 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10684 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10686 MachineBasicBlock *StartMBB =
nullptr;
10687 MachineBasicBlock *LoopMBB =
nullptr;
10688 MachineBasicBlock *NextMBB =
nullptr;
10689 MachineBasicBlock *DoneMBB =
nullptr;
10690 MachineBasicBlock *AllDoneMBB =
nullptr;
10694 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10703 RC = &SystemZ::GR64BitRegClass;
10731 MBB = MemsetOneCheckMBB;
10742 MBB = MemsetOneMBB;
10774 if (EndMBB && !ImmLength)
10796 if (!HaveSingleBase)
10803 if (Opcode == SystemZ::MVC)
10830 if (!HaveSingleBase)
10855 Register RemDestReg = HaveSingleBase ? RemSrcReg
10860 if (!HaveSingleBase)
10868 MachineInstrBuilder EXRL_MIB =
10876 if (Opcode != SystemZ::MVC) {
10886 while (ImmLength > 0) {
10890 foldDisplIfNeeded(DestBase, DestDisp);
10891 foldDisplIfNeeded(SrcBase, SrcDisp);
10892 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10893 DestDisp += ThisLength;
10894 SrcDisp += ThisLength;
10895 ImmLength -= ThisLength;
10898 if (EndMBB && ImmLength > 0) {
10914 MI.eraseFromParent();
10921 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10927 assert(Len > 0 && Len <= 256 &&
"Memmove of of unsupported constant length.");
10956 MI.eraseFromParent();
10965 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10969 uint64_t End1Reg =
MI.getOperand(0).getReg();
10970 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10971 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10972 uint64_t CharReg =
MI.getOperand(3).getReg();
10979 MachineBasicBlock *StartMBB =
MBB;
11015 MI.eraseFromParent();
11022 bool NoFloat)
const {
11024 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
11025 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11028 MI.setDesc(
TII->get(Opcode));
11032 uint64_t Control =
MI.getOperand(2).getImm();
11033 static const unsigned GPRControlBit[16] = {
11034 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
11035 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
11037 Control |= GPRControlBit[15];
11038 if (TFI->
hasFP(MF))
11039 Control |= GPRControlBit[11];
11040 MI.getOperand(2).setImm(Control);
11043 for (
int I = 0;
I < 16;
I++) {
11044 if ((Control & GPRControlBit[
I]) == 0) {
11051 if (!NoFloat && (Control & 4) != 0) {
11052 if (Subtarget.hasVector()) {
11069 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11070 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11073 Register SrcReg =
MI.getOperand(0).getReg();
11084 MI.eraseFromParent();
11092 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11093 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11096 Register DstReg =
MI.getOperand(0).getReg();
11097 Register SizeReg =
MI.getOperand(2).getReg();
11099 MachineBasicBlock *StartMBB =
MBB;
11186 MI.eraseFromParent();
11190SDValue SystemZTargetLowering::
11193 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11205 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11210 .
addImm(
MI.getOperand(1).getImm());
11211 MI.eraseFromParent();
11217 switch (
MI.getOpcode()) {
11218 case SystemZ::ADJCALLSTACKDOWN:
11219 case SystemZ::ADJCALLSTACKUP:
11220 return emitAdjCallStack(
MI,
MBB);
11222 case SystemZ::Select32:
11223 case SystemZ::Select64:
11224 case SystemZ::Select128:
11225 case SystemZ::SelectF32:
11226 case SystemZ::SelectF64:
11227 case SystemZ::SelectF128:
11228 case SystemZ::SelectVR32:
11229 case SystemZ::SelectVR64:
11230 case SystemZ::SelectVR128:
11231 return emitSelect(
MI,
MBB);
11233 case SystemZ::CondStore8Mux:
11234 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11235 case SystemZ::CondStore8MuxInv:
11236 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11237 case SystemZ::CondStore16Mux:
11238 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11239 case SystemZ::CondStore16MuxInv:
11240 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11241 case SystemZ::CondStore32Mux:
11242 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11243 case SystemZ::CondStore32MuxInv:
11244 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11245 case SystemZ::CondStore8:
11246 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11247 case SystemZ::CondStore8Inv:
11248 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11249 case SystemZ::CondStore16:
11250 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11251 case SystemZ::CondStore16Inv:
11252 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11253 case SystemZ::CondStore32:
11254 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11255 case SystemZ::CondStore32Inv:
11256 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11257 case SystemZ::CondStore64:
11258 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11259 case SystemZ::CondStore64Inv:
11260 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11261 case SystemZ::CondStoreF32:
11262 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11263 case SystemZ::CondStoreF32Inv:
11264 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11265 case SystemZ::CondStoreF64:
11266 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11267 case SystemZ::CondStoreF64Inv:
11268 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11270 case SystemZ::SCmp128Hi:
11271 return emitICmp128Hi(
MI,
MBB,
false);
11272 case SystemZ::UCmp128Hi:
11273 return emitICmp128Hi(
MI,
MBB,
true);
11275 case SystemZ::PAIR128:
11276 return emitPair128(
MI,
MBB);
11277 case SystemZ::AEXT128:
11278 return emitExt128(
MI,
MBB,
false);
11279 case SystemZ::ZEXT128:
11280 return emitExt128(
MI,
MBB,
true);
11282 case SystemZ::ATOMIC_SWAPW:
11283 return emitAtomicLoadBinary(
MI,
MBB, 0);
11285 case SystemZ::ATOMIC_LOADW_AR:
11286 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11287 case SystemZ::ATOMIC_LOADW_AFI:
11288 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11290 case SystemZ::ATOMIC_LOADW_SR:
11291 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11293 case SystemZ::ATOMIC_LOADW_NR:
11294 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11295 case SystemZ::ATOMIC_LOADW_NILH:
11296 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11298 case SystemZ::ATOMIC_LOADW_OR:
11299 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11300 case SystemZ::ATOMIC_LOADW_OILH:
11301 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11303 case SystemZ::ATOMIC_LOADW_XR:
11304 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11305 case SystemZ::ATOMIC_LOADW_XILF:
11306 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11308 case SystemZ::ATOMIC_LOADW_NRi:
11309 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11310 case SystemZ::ATOMIC_LOADW_NILHi:
11311 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11313 case SystemZ::ATOMIC_LOADW_MIN:
11315 case SystemZ::ATOMIC_LOADW_MAX:
11317 case SystemZ::ATOMIC_LOADW_UMIN:
11319 case SystemZ::ATOMIC_LOADW_UMAX:
11322 case SystemZ::ATOMIC_CMP_SWAPW:
11323 return emitAtomicCmpSwapW(
MI,
MBB);
11324 case SystemZ::MVCImm:
11325 case SystemZ::MVCReg:
11326 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11327 case SystemZ::NCImm:
11328 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11329 case SystemZ::OCImm:
11330 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11331 case SystemZ::XCImm:
11332 case SystemZ::XCReg:
11333 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11334 case SystemZ::CLCImm:
11335 case SystemZ::CLCReg:
11336 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11337 case SystemZ::MemsetImmImm:
11338 case SystemZ::MemsetImmReg:
11339 case SystemZ::MemsetRegImm:
11340 case SystemZ::MemsetRegReg:
11341 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11342 case SystemZ::MemmoveImm:
11343 return emitMemmoveImm(
MI,
MBB);
11344 case SystemZ::CLSTLoop:
11345 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11346 case SystemZ::MVSTLoop:
11347 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11348 case SystemZ::SRSTLoop:
11349 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11350 case SystemZ::TBEGIN:
11351 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11352 case SystemZ::TBEGIN_nofloat:
11353 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11354 case SystemZ::TBEGINC:
11355 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11356 case SystemZ::LTEBRCompare_Pseudo:
11357 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11358 case SystemZ::LTDBRCompare_Pseudo:
11359 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11360 case SystemZ::LTXBRCompare_Pseudo:
11361 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11363 case SystemZ::PROBED_ALLOCA:
11364 return emitProbedAlloca(
MI,
MBB);
11365 case SystemZ::EH_SjLj_SetJmp:
11367 case SystemZ::EH_SjLj_LongJmp:
11370 case TargetOpcode::STACKMAP:
11371 case TargetOpcode::PATCHPOINT:
11374 case SystemZ::MOV_STACKGUARD_DAG:
11375 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11377 case SystemZ::CMP_STACKGUARD_DAG:
11378 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11388SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11389 if (VT == MVT::Untyped)
11390 return &SystemZ::ADDR128BitRegClass;
11416 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11436 EVT VT =
Op.getValueType();
11437 Op =
Op.getOperand(0);
11438 EVT OpVT =
Op.getValueType();
11440 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11451 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11472 if (Attrs.hasRetAttrs())
11473 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11474 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11475 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11478 OS << *FT->getParamType(
I);
11480 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11487bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11488 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11489 if (Itr == IsInternalCache.end())
11490 Itr = IsInternalCache
11491 .insert(std::pair<const Function *, bool>(
11494 return Itr->second;
11497void SystemZTargetLowering::
11505 bool IsInternal =
false;
11506 const Function *CalleeFn =
nullptr;
11509 IsInternal = isInternal(CalleeFn);
11510 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11511 errs() <<
"ERROR: Missing extension attribute of passed "
11512 <<
"value in call to function:\n" <<
"Callee: ";
11513 if (CalleeFn !=
nullptr)
11517 errs() <<
"Caller: ";
11523void SystemZTargetLowering::
11531 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11532 errs() <<
"ERROR: Missing extension attribute of returned "
11533 <<
"value from function:\n";
11541bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11543 if (!Subtarget.isTargetELF())
11552 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11553 MVT VT = Outs[i].VT;
11554 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11557 "Unexpected integer argument VT.");
11558 if (VT == MVT::i32 &&
11569 StringRef GuardMode = M.getStackProtectorGuard();
11572 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.
LLVM_ABI unsigned getPointerSize(unsigned AS=0) const
The pointer representation size in bytes, rounded up to a whole number of bytes.
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 or function.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
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.
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...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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 & setOperandDead(unsigned OpIdx) 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.
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.
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...
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 ...
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 getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS, const SDNodeFlags Flags=SDNodeFlags())
Return an AddrSpaceCastSDNode.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
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 getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
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 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 MMOMetadata &Metadata=MMOMetadata())
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 getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
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.
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.
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.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
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.
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
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.
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...
@ Fast
Assign the register banks as fast as possible (default).
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.