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();
867 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
869 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16)) {
870 IntermediateVT = RegisterVT = MVT::v8f16;
871 return NumIntermediates =
875 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
887 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
895 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
922 return Subtarget.hasVectorEnhancements1();
935 if (!Subtarget.hasVector() ||
936 (isFP128 && !Subtarget.hasVectorEnhancements1()))
945 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
952 Opcode = SystemZISD::BYTE_MASK;
958 if (SplatBitSize > 64)
961 auto TryValue = [&](uint64_t
Value) ->
bool {
965 OpVals.push_back(((
unsigned) SignedValue));
966 Opcode = SystemZISD::REPLICATE;
973 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start,
End)) {
977 OpVals.push_back(Start - (64 - SplatBitSize));
978 OpVals.push_back(
End - (64 - SplatBitSize));
979 Opcode = SystemZISD::ROTATE_MASK;
991 uint64_t SplatBitsZ = SplatBits.getZExtValue();
992 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
1004 return TryValue(SplatBitsZ | Middle);
1013 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
1019 unsigned HalfSize = Width / 2;
1024 if (HighValue != LowValue || 8 > HalfSize)
1027 SplatBits = HighValue;
1031 SplatBitSize = Width;
1039 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1043 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1048 bool ForCodeSize)
const {
1050 if (
Imm.isZero() ||
Imm.isNegZero())
1071 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1077 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1130 const int64_t FPOffset = 0;
1151 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1152 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1155 .
addReg(SpecialRegs->getFramePointerRegister())
1163 .
addReg(SpecialRegs->getStackPointerRegister())
1174 .
addReg(SpecialRegs->getStackPointerRegister())
1175 .
addImm(TFL->getBackchainOffset(*MF))
1186 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1190 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1211 MI.eraseFromParent();
1227 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1230 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1237 const int64_t FPOffset = 0;
1249 SpecialRegs->getFramePointerRegister())
1271 SpecialRegs->getStackPointerRegister())
1280 .
addReg(SpecialRegs->getStackPointerRegister())
1281 .
addImm(TFL->getBackchainOffset(*MF))
1287 MI.eraseFromParent();
1318 if (Subtarget.hasInterlockedAccess1() &&
1351 EVT VT =
Y.getValueType();
1354 if (VT == MVT::i32 || VT == MVT::i64)
1355 return Subtarget.hasMiscellaneousExtensions3();
1358 if (VT.
isVector() || VT == MVT::i128)
1359 return Subtarget.hasVector();
1387 bool MVC = Ty->isIntegerTy(8);
1393static AddressingMode
1396 switch (
II->getIntrinsicID()) {
1398 case Intrinsic::memset:
1399 case Intrinsic::memmove:
1400 case Intrinsic::memcpy:
1407 if (SingleUser->getParent() ==
I->getParent()) {
1410 if (
C->getBitWidth() <= 64 &&
1420 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1434 I->getOperand(0)->getType());
1436 bool IsVectorAccess = MemAccessTy->isVectorTy();
1441 Value *DataOp =
I->getOperand(0);
1443 IsVectorAccess =
true;
1449 User *LoadUser = *
I->user_begin();
1451 IsVectorAccess =
true;
1454 if (IsFPAccess || IsVectorAccess)
1473 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1483 return AM.
Scale == 0;
1490 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1491 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1495 "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
1497 if (
Op.isZeroMemset())
1500 const int MVCFastLen = 16;
1503 if (
Op.isMemcpy() &&
Op.size() <= MVCFastLen)
1505 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1509 if ((
Op.size() >= 16 && !
Op.isAligned(
Align(8))) ||
1510 (
Op.size() >= 25 &&
Op.size() <= 31))
1514 Context, MemOps, Limit,
Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1520 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1524 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1526 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1528 return FromBits > ToBits;
1536 return FromBits > ToBits;
1545 if (Constraint.
size() == 1) {
1546 switch (Constraint[0]) {
1572 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1573 switch (Constraint[1]) {
1584 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1594 Value *CallOperandVal = Info.CallOperandVal;
1597 if (!CallOperandVal)
1601 switch (*Constraint) {
1620 if (Subtarget.hasVector())
1651 if (
C->getZExtValue() == 0x7fffffff)
1661static std::pair<unsigned, const TargetRegisterClass *>
1663 const unsigned *Map,
unsigned Size) {
1664 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1665 if (isdigit(Constraint[2])) {
1670 return std::make_pair(Map[Index], RC);
1672 return std::make_pair(0U,
nullptr);
1675std::pair<unsigned, const TargetRegisterClass *>
1678 if (Constraint.
size() == 1) {
1680 switch (Constraint[0]) {
1685 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1687 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1688 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1692 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1693 else if (VT == MVT::i128)
1694 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1695 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1698 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1703 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1705 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1707 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1708 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1713 if (Subtarget.hasVector()) {
1715 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1717 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1719 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1720 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1729 auto getVTSizeInBits = [&VT]() {
1737 if (Constraint[1] ==
'r') {
1738 if (getVTSizeInBits() == 32)
1741 if (getVTSizeInBits() == 128)
1747 if (Constraint[1] ==
'f') {
1749 return std::make_pair(
1751 if (getVTSizeInBits() == 16)
1754 if (getVTSizeInBits() == 32)
1757 if (getVTSizeInBits() == 128)
1763 if (Constraint[1] ==
'v') {
1764 if (!Subtarget.hasVector())
1765 return std::make_pair(
1767 if (getVTSizeInBits() == 16)
1770 if (getVTSizeInBits() == 32)
1773 if (getVTSizeInBits() == 64)
1779 if (Constraint[1] ==
'@') {
1780 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1781 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1794 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1795 : SystemZ::NoRegister)
1797 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1805 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1810 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1825 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1829 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1830 OpInfo.ConstraintVT.getSizeInBits() < 8)
1845 if (Constraint.
size() == 1) {
1846 switch (Constraint[0]) {
1851 Op.getValueType()));
1858 Op.getValueType()));
1865 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1872 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1877 if (
C->getZExtValue() == 0x7fffffff)
1879 Op.getValueType()));
1890#define GET_CALLING_CONV_IMPL
1891#include "SystemZGenCallingConv.inc"
1895 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1901 Type *ToType)
const {
1964 if (BitCastToType == MVT::v2i64)
1991 MVT::Untyped,
Hi,
Lo);
2015 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
2017 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2028 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
2029 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2040template <
class ArgTy>
2043 MVT &PartVT,
unsigned &NumParts) {
2044 if (!Args[
I].Flags.isSplit())
2048 PartVT = ArgLocs[
I].getValVT();
2050 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2051 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2052 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2054 if (Args[PartIdx].Flags.isSplitEnd())
2078 unsigned NumFixedGPRs = 0;
2079 unsigned NumFixedFPRs = 0;
2080 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2093 RC = &SystemZ::GR32BitRegClass;
2097 RC = &SystemZ::GR64BitRegClass;
2101 RC = &SystemZ::FP16BitRegClass;
2105 RC = &SystemZ::FP32BitRegClass;
2109 RC = &SystemZ::FP64BitRegClass;
2113 RC = &SystemZ::FP128BitRegClass;
2122 RC = &SystemZ::VR128BitRegClass;
2136 if (Subtarget.isTargetXPLINK64()) {
2139 ArgSPOffset += XPRegs.getCallFrameSize();
2150 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2154 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2168 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2171 unsigned PartOffset = Ins[
I].PartOffset;
2176 assert(PartOffset &&
"Offset should be non-zero.");
2179 }
else if (Subtarget.isTargetXPLINK64() &&
2182 Ins[
I].ArgVT.isSimple()) {
2187 MVT OrigVT = Ins[
I].ArgVT.getSimpleVT();
2193 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2199 Subtarget.getSpecialRegisters());
2205 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2210 if (IsVarArg && Subtarget.isTargetELF()) {
2223 int64_t RegSaveOffset =
2238 &SystemZ::FP64BitRegClass);
2250 if (Subtarget.isTargetXPLINK64()) {
2255 Subtarget.getSpecialRegisters());
2256 MRI.
addLiveIn(Regs->getADARegister(), ADAvReg);
2268 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2275 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2277 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2284 unsigned Offset,
bool LoadAdr =
false) {
2307 bool LoadAddr =
false;
2329 unsigned ADADelta = 0;
2330 unsigned EPADelta = 8;
2336 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2337 G->getGlobal()->hasPrivateLinkage());
2344 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2390 if (Subtarget.isTargetXPLINK64())
2394 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2398 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2417 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2425 unsigned NumParts = 1;
2429 SlotVT = Outs[
I].VT;
2436 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2439 assert(Outs[
I].PartOffset == 0);
2440 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2443 unsigned PartOffset = Outs[
I].PartOffset;
2449 assert(PartOffset &&
"Offset should be non-zero.");
2451 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2453 ArgValue = SpillSlot;
2470 if (!StackPtr.getNode())
2477 else if (VA.
getLocVT() == MVT::f16)
2490 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2494 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2500 if (!MemOpChains.
empty())
2508 if (Subtarget.isTargetXPLINK64()) {
2513 ->getAddressOfCalleeRegister();
2516 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2523 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2526 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2527 }
else if (IsTailCall) {
2530 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2535 for (
const auto &[Reg,
N] : RegsToPass) {
2542 Ops.push_back(Chain);
2543 Ops.push_back(Callee);
2547 for (
const auto &[Reg,
N] : RegsToPass)
2552 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2553 assert(Mask &&
"Missing call preserved mask for calling convention");
2558 Ops.push_back(Glue);
2567 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2577 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2584 VA.getLocVT(), Glue);
2601 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2603 Args.reserve(
Ops.size());
2609 Entry.IsZExt = !Entry.IsSExt;
2610 Args.push_back(Entry);
2621 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2632 const Type *RetTy)
const {
2635 for (
auto &Out : Outs)
2636 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2640 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2641 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2653 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2661 if (RetLocs.
empty())
2662 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2671 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2693 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2700 unsigned &CCValid) {
2701 unsigned Id =
Op.getConstantOperandVal(1);
2703 case Intrinsic::s390_tbegin:
2704 Opcode = SystemZISD::TBEGIN;
2708 case Intrinsic::s390_tbegin_nofloat:
2709 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2713 case Intrinsic::s390_tend:
2714 Opcode = SystemZISD::TEND;
2727 unsigned Id =
Op.getConstantOperandVal(0);
2729 case Intrinsic::s390_vpkshs:
2730 case Intrinsic::s390_vpksfs:
2731 case Intrinsic::s390_vpksgs:
2732 Opcode = SystemZISD::PACKS_CC;
2736 case Intrinsic::s390_vpklshs:
2737 case Intrinsic::s390_vpklsfs:
2738 case Intrinsic::s390_vpklsgs:
2739 Opcode = SystemZISD::PACKLS_CC;
2743 case Intrinsic::s390_vceqbs:
2744 case Intrinsic::s390_vceqhs:
2745 case Intrinsic::s390_vceqfs:
2746 case Intrinsic::s390_vceqgs:
2747 case Intrinsic::s390_vceqqs:
2748 Opcode = SystemZISD::VICMPES;
2752 case Intrinsic::s390_vchbs:
2753 case Intrinsic::s390_vchhs:
2754 case Intrinsic::s390_vchfs:
2755 case Intrinsic::s390_vchgs:
2756 case Intrinsic::s390_vchqs:
2757 Opcode = SystemZISD::VICMPHS;
2761 case Intrinsic::s390_vchlbs:
2762 case Intrinsic::s390_vchlhs:
2763 case Intrinsic::s390_vchlfs:
2764 case Intrinsic::s390_vchlgs:
2765 case Intrinsic::s390_vchlqs:
2766 Opcode = SystemZISD::VICMPHLS;
2770 case Intrinsic::s390_vtm:
2771 Opcode = SystemZISD::VTM;
2775 case Intrinsic::s390_vfaebs:
2776 case Intrinsic::s390_vfaehs:
2777 case Intrinsic::s390_vfaefs:
2778 Opcode = SystemZISD::VFAE_CC;
2782 case Intrinsic::s390_vfaezbs:
2783 case Intrinsic::s390_vfaezhs:
2784 case Intrinsic::s390_vfaezfs:
2785 Opcode = SystemZISD::VFAEZ_CC;
2789 case Intrinsic::s390_vfeebs:
2790 case Intrinsic::s390_vfeehs:
2791 case Intrinsic::s390_vfeefs:
2792 Opcode = SystemZISD::VFEE_CC;
2796 case Intrinsic::s390_vfeezbs:
2797 case Intrinsic::s390_vfeezhs:
2798 case Intrinsic::s390_vfeezfs:
2799 Opcode = SystemZISD::VFEEZ_CC;
2803 case Intrinsic::s390_vfenebs:
2804 case Intrinsic::s390_vfenehs:
2805 case Intrinsic::s390_vfenefs:
2806 Opcode = SystemZISD::VFENE_CC;
2810 case Intrinsic::s390_vfenezbs:
2811 case Intrinsic::s390_vfenezhs:
2812 case Intrinsic::s390_vfenezfs:
2813 Opcode = SystemZISD::VFENEZ_CC;
2817 case Intrinsic::s390_vistrbs:
2818 case Intrinsic::s390_vistrhs:
2819 case Intrinsic::s390_vistrfs:
2820 Opcode = SystemZISD::VISTR_CC;
2824 case Intrinsic::s390_vstrcbs:
2825 case Intrinsic::s390_vstrchs:
2826 case Intrinsic::s390_vstrcfs:
2827 Opcode = SystemZISD::VSTRC_CC;
2831 case Intrinsic::s390_vstrczbs:
2832 case Intrinsic::s390_vstrczhs:
2833 case Intrinsic::s390_vstrczfs:
2834 Opcode = SystemZISD::VSTRCZ_CC;
2838 case Intrinsic::s390_vstrsb:
2839 case Intrinsic::s390_vstrsh:
2840 case Intrinsic::s390_vstrsf:
2841 Opcode = SystemZISD::VSTRS_CC;
2845 case Intrinsic::s390_vstrszb:
2846 case Intrinsic::s390_vstrszh:
2847 case Intrinsic::s390_vstrszf:
2848 Opcode = SystemZISD::VSTRSZ_CC;
2852 case Intrinsic::s390_vfcedbs:
2853 case Intrinsic::s390_vfcesbs:
2854 Opcode = SystemZISD::VFCMPES;
2858 case Intrinsic::s390_vfchdbs:
2859 case Intrinsic::s390_vfchsbs:
2860 Opcode = SystemZISD::VFCMPHS;
2864 case Intrinsic::s390_vfchedbs:
2865 case Intrinsic::s390_vfchesbs:
2866 Opcode = SystemZISD::VFCMPHES;
2870 case Intrinsic::s390_vftcidb:
2871 case Intrinsic::s390_vftcisb:
2872 Opcode = SystemZISD::VFTCI;
2876 case Intrinsic::s390_tdc:
2877 Opcode = SystemZISD::TDC;
2890 unsigned NumOps =
Op.getNumOperands();
2893 Ops.push_back(
Op.getOperand(0));
2895 Ops.push_back(
Op.getOperand(
I));
2897 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2911 unsigned NumOps =
Op.getNumOperands();
2917 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2918 "Unhandled intrinsic with f16 operand.");
2921 Ops.push_back(CurrOper);
2935 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2936 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2937 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2963 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2966 int64_t
Value = ConstOp1->getSExtValue();
2982 if (!
C.Op0.hasOneUse() ||
2989 unsigned NumBits =
Load->getMemoryVT().getSizeInBits();
2990 if ((NumBits != 8 && NumBits != 16) ||
2991 NumBits !=
Load->getMemoryVT().getStoreSizeInBits())
2997 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
3000 uint64_t Mask = (1 << NumBits) - 1;
3003 int64_t SignedValue = ConstOp1->getSExtValue();
3010 }
else if (NumBits == 8) {
3036 if (
C.Op0.getValueType() != MVT::i32 ||
3037 Load->getExtensionType() != ExtType) {
3039 Load->getBasePtr(),
Load->getPointerInfo(),
3040 Load->getMemoryVT(),
Load->getAlign(),
3041 Load->getMemOperand()->getFlags());
3047 if (
C.Op1.getValueType() != MVT::i32 ||
3048 Value != ConstOp1->getZExtValue())
3058 if (
Load->getMemoryVT() == MVT::i8)
3061 switch (
Load->getExtensionType()) {
3079 if (
C.Op0.isMachineOpcode() &&
3080 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3084 if (
C.Op0.getValueType() == MVT::i128)
3086 if (
C.Op0.getValueType() == MVT::f128)
3098 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3127 unsigned Opcode0 =
C.Op0.getOpcode();
3134 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3149 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3150 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3172 if (C1 && C1->isZero()) {
3191 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3194 if (C1 && C1->getZExtValue() == 32) {
3195 SDValue ShlOp0 =
C.Op0.getOperand(0);
3214 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3217 C.Op1->getAsZExtVal() == 0) {
3219 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3220 C.Op0.getValueSizeInBits().getFixedValue()) {
3221 unsigned Type = L->getExtensionType();
3224 C.Op0 =
C.Op0.getOperand(0);
3240 if (
C.Opcode != SystemZISD::ICMP)
3250 if (!
C.Op1.isMachineOpcode() ||
3251 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3256 C.Opcode = SystemZISD::CMP_STACKGUARD;
3267 uint64_t Amount = Shift->getZExtValue();
3268 if (Amount >=
N.getValueSizeInBits())
3283 unsigned ICmpType) {
3284 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3306 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3312 if (EffectivelyUnsigned && CmpVal <
Low) {
3320 if (CmpVal == Mask) {
3326 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3332 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3340 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3346 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3375 if (
C.Op0.getValueType() == MVT::i128) {
3381 if (Mask && Mask->getAPIntValue() == 0) {
3382 C.Opcode = SystemZISD::VTM;
3399 uint64_t CmpVal = ConstOp1->getZExtValue();
3406 NewC.Op0 =
C.Op0.getOperand(0);
3407 NewC.Op1 =
C.Op0.getOperand(1);
3411 MaskVal = Mask->getZExtValue();
3431 MaskVal = -(CmpVal & -CmpVal);
3440 unsigned NewCCMask, ShiftVal;
3444 (MaskVal >> ShiftVal != 0) &&
3445 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3447 MaskVal >> ShiftVal,
3451 MaskVal >>= ShiftVal;
3455 (MaskVal << ShiftVal != 0) &&
3456 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3458 MaskVal << ShiftVal,
3462 MaskVal <<= ShiftVal;
3471 C.Opcode = SystemZISD::TM;
3473 if (Mask && Mask->getZExtValue() == MaskVal)
3478 C.CCMask = NewCCMask;
3484 if (
C.Opcode != SystemZISD::ICMP)
3486 if (
C.Op0.getValueType() != MVT::i128)
3497 Src = Src.getOperand(0);
3500 unsigned Opcode = 0;
3501 if (Src.hasOneUse()) {
3502 switch (Src.getOpcode()) {
3503 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3504 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3505 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3506 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3507 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3508 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3514 C.Op0 = Src->getOperand(0);
3515 C.Op1 = Src->getOperand(1);
3519 C.CCMask ^=
C.CCValid;
3531 C.Opcode = SystemZISD::VICMPES;
3543 bool Swap =
false, Invert =
false;
3555 C.Opcode = SystemZISD::UCMP128HI;
3557 C.Opcode = SystemZISD::SCMP128HI;
3562 C.CCMask ^=
C.CCValid;
3573 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3576 if ((~
Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3579 C.Op0 =
C.Op0.getOperand(0);
3591 C.CCValid = CCValid;
3594 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3597 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3601 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3604 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3608 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3611 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3614 C.CCMask &= CCValid;
3622 bool IsSignaling =
false) {
3625 unsigned Opcode, CCValid;
3637 Comparison
C(CmpOp0, CmpOp1, Chain);
3639 if (
C.Op0.getValueType().isFloatingPoint()) {
3642 C.Opcode = SystemZISD::FCMP;
3643 else if (!IsSignaling)
3644 C.Opcode = SystemZISD::STRICT_FCMP;
3646 C.Opcode = SystemZISD::STRICT_FCMPS;
3651 C.Opcode = SystemZISD::ICMP;
3687 if (!
C.Op1.getNode()) {
3688 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3689 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3691 switch (
C.Op0.getOpcode()) {
3702 if (
C.Opcode == SystemZISD::ICMP)
3703 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3705 if (
C.Opcode == SystemZISD::TM) {
3708 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3711 if (
C.Opcode == SystemZISD::VICMPES ||
3712 C.Opcode == SystemZISD::VICMPHS ||
3713 C.Opcode == SystemZISD::VICMPHLS ||
3714 C.Opcode == SystemZISD::VFCMPES ||
3715 C.Opcode == SystemZISD::VFCMPHS ||
3716 C.Opcode == SystemZISD::VFCMPHES) {
3717 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3724 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3726 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3735 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3736 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3761 unsigned CCValid,
unsigned CCMask) {
3766 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3844 int Mask[] = { Start, -1, Start + 1, -1 };
3848 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3850 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3864 !Subtarget.hasVectorEnhancements1()) {
3870 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3871 SDValue HRes = DAG.
getNode(Opcode,
DL, VTs, Chain, H0, H1);
3872 SDValue LRes = DAG.
getNode(Opcode,
DL, VTs, Chain, L0, L1);
3873 SDValue Res = DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3878 SDValue
Ops[2] = { Res, NewChain };
3881 SDValue HRes = DAG.
getNode(Opcode,
DL, MVT::v2i64, H0, H1);
3882 SDValue LRes = DAG.
getNode(Opcode,
DL, MVT::v2i64, L0, L1);
3883 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3886 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3887 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3889 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3902 bool IsSignaling)
const {
3905 assert (!IsSignaling || Chain);
3908 bool Invert =
false;
3916 assert(IsFP &&
"Unexpected integer comparison");
3918 DL, VT, CmpOp1, CmpOp0, Chain);
3920 DL, VT, CmpOp0, CmpOp1, Chain);
3924 LT.getValue(1),
GE.getValue(1));
3933 assert(IsFP &&
"Unexpected integer comparison");
3935 DL, VT, CmpOp1, CmpOp0, Chain);
3937 DL, VT, CmpOp0, CmpOp1, Chain);
3941 LT.getValue(1),
GT.getValue(1));
3962 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3966 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3971 Chain =
Cmp.getValue(1);
3979 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3980 SDValue
Ops[2] = {
Cmp, Chain };
3988 SDValue CmpOp0 =
Op.getOperand(0);
3989 SDValue CmpOp1 =
Op.getOperand(1);
3992 EVT VT =
Op.getValueType();
3994 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
4003 bool IsSignaling)
const {
4004 SDValue Chain =
Op.getOperand(0);
4005 SDValue CmpOp0 =
Op.getOperand(1);
4006 SDValue CmpOp1 =
Op.getOperand(2);
4009 EVT VT =
Op.getNode()->getValueType(0);
4011 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
4012 Chain, IsSignaling);
4026 SDValue CmpOp0 =
Op.getOperand(2);
4027 SDValue CmpOp1 =
Op.getOperand(3);
4028 SDValue Dest =
Op.getOperand(4);
4034 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4068 C.CCMask ^=
C.CCValid;
4076 Op = SystemZISD::VICMPE;
4080 Op = SystemZISD::VICMPHL;
4082 Op = SystemZISD::VICMPH;
4097 SDValue CmpOp0 =
Op.getOperand(0);
4098 SDValue CmpOp1 =
Op.getOperand(1);
4099 SDValue TrueOp =
Op.getOperand(2);
4100 SDValue FalseOp =
Op.getOperand(3);
4121 C.Op1->getAsZExtVal() == 0) {
4128 if (Subtarget.hasVectorEnhancements3() &&
4129 C.Opcode == SystemZISD::ICMP &&
4130 C.Op0.getValueType() == MVT::i128 &&
4136 SDValue
Ops[] = {TrueOp, FalseOp,
4140 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4146 const GlobalValue *GV =
Node->getGlobal();
4152 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4174 }
else if (Subtarget.isTargetELF()) {
4179 }
else if (Subtarget.isTargetzOS()) {
4210 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4215 Ops.push_back(Chain);
4217 Node->getValueType(0),
4226 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4227 const uint32_t *
Mask =
4229 assert(Mask &&
"Missing call preserved mask for calling convention");
4233 Ops.push_back(Glue);
4236 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4244SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4268 const GlobalValue *GV =
Node->getGlobal();
4276 SDValue TP = lowerThreadPointer(
DL, DAG);
4283 SystemZConstantPoolValue *CPV =
4292 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4298 SystemZConstantPoolValue *CPV =
4307 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4312 SystemZMachineFunctionInfo* MFI =
4341 SystemZConstantPoolValue *CPV =
4375 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4392 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4397 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4399 MachineFrameInfo &MFI = MF.getFrameInfo();
4403 unsigned Depth =
Op.getConstantOperandVal(0);
4410 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4415 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4421 MachinePointerInfo());
4436 unsigned Depth =
Op.getConstantOperandVal(0);
4441 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4444 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4445 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4446 int Offset = TFL->getReturnAddressOffset(MF);
4450 MachinePointerInfo());
4455 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4457 &SystemZ::GR64BitRegClass);
4464 SDValue
In =
Op.getOperand(0);
4465 EVT InVT =
In.getValueType();
4466 EVT ResVT =
Op.getValueType();
4473 SDValue NewLoad = DAG.
getLoad(ResVT,
DL, LoadN->getChain(),
4474 LoadN->getBasePtr(), LoadN->getMemOperand());
4480 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4482 if (Subtarget.hasHighWord()) {
4486 MVT::i64, SDValue(U64, 0), In);
4494 DL, MVT::f32, Out64);
4496 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4499 MVT::f64, SDValue(U64, 0), In);
4501 if (Subtarget.hasHighWord())
4514 if (Subtarget.isTargetXPLINK64())
4515 return lowerVASTART_XPLINK(
Op, DAG);
4517 return lowerVASTART_ELF(
Op, DAG);
4523 SystemZMachineFunctionInfo *FuncInfo =
4524 MF.
getInfo<SystemZMachineFunctionInfo>();
4534 MachinePointerInfo(SV));
4540 SystemZMachineFunctionInfo *FuncInfo =
4541 MF.
getInfo<SystemZMachineFunctionInfo>();
4544 SDValue Chain =
Op.getOperand(0);
4545 SDValue Addr =
Op.getOperand(1);
4550 const unsigned NumFields = 4;
4551 SDValue Fields[NumFields] = {
4559 SDValue MemOps[NumFields];
4561 for (
unsigned I = 0;
I < NumFields; ++
I) {
4562 SDValue FieldAddr = Addr;
4566 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4567 MachinePointerInfo(SV,
Offset));
4575 SDValue Chain =
Op.getOperand(0);
4576 SDValue DstPtr =
Op.getOperand(1);
4577 SDValue SrcPtr =
Op.getOperand(2);
4587 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4588 MachinePointerInfo(SrcSV));
4592SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4594 if (Subtarget.isTargetXPLINK64())
4595 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4597 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4601SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4603 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4606 SDValue Chain =
Op.getOperand(0);
4607 SDValue
Size =
Op.getOperand(1);
4608 SDValue
Align =
Op.getOperand(2);
4613 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4616 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4617 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4619 SDValue NeededSpace =
Size;
4623 if (ExtraAlignSpace)
4627 bool IsSigned =
false;
4628 bool DoesNotReturn =
false;
4629 bool IsReturnValueUsed =
false;
4630 EVT VT =
Op.getValueType();
4631 SDValue AllocaCall =
4640 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4643 SDValue Glue = AllocaCall.
getValue(2);
4648 SDValue ArgAdjust = DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, PtrMVT);
4652 if (ExtraAlignSpace) {
4664SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4666 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4669 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4671 SDValue Chain =
Op.getOperand(0);
4672 SDValue
Size =
Op.getOperand(1);
4673 SDValue
Align =
Op.getOperand(2);
4678 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4681 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4682 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4685 SDValue NeededSpace =
Size;
4693 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4694 MachinePointerInfo());
4697 if (ExtraAlignSpace)
4704 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4705 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4717 SDValue ArgAdjust = DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4721 if (RequiredAlign > StackAlign) {
4731 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4732 MachinePointerInfo());
4738SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4742 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4747 unsigned Opcode)
const {
4748 EVT VT =
Op.getValueType();
4754 assert(Subtarget.hasMiscellaneousExtensions2());
4759 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4765 EVT VT =
Op.getValueType();
4773 else if (Subtarget.hasMiscellaneousExtensions2())
4778 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4794 SDValue LL =
Op.getOperand(0);
4795 SDValue RL =
Op.getOperand(1);
4813 EVT VT =
Op.getValueType();
4826 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4832 SDValue Op0 =
Op.getOperand(0);
4833 SDValue Op1 =
Op.getOperand(1);
4834 EVT VT =
Op.getValueType();
4854 EVT VT =
Op.getValueType();
4861 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4866 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4869 SDValue
Ops[] = {
Op.getOperand(0),
Op.getOperand(1)};
4876 Known[1].Zero.getZExtValue() };
4878 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4880 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4885 SDValue LowOp =
Ops[
Low];
4917 MVT::i64, HighOp, Low32);
4923 SDNode *
N =
Op.getNode();
4924 SDValue
LHS =
N->getOperand(0);
4925 SDValue
RHS =
N->getOperand(1);
4928 if (
N->getValueType(0) == MVT::i128) {
4929 unsigned BaseOp = 0;
4930 unsigned FlagOp = 0;
4931 bool IsBorrow =
false;
4932 switch (
Op.getOpcode()) {
4936 FlagOp = SystemZISD::VACC;
4940 FlagOp = SystemZISD::VSCBI;
4955 unsigned BaseOp = 0;
4956 unsigned CCValid = 0;
4957 unsigned CCMask = 0;
4959 switch (
Op.getOpcode()) {
4962 BaseOp = SystemZISD::SADDO;
4967 BaseOp = SystemZISD::SSUBO;
4972 BaseOp = SystemZISD::UADDO;
4977 BaseOp = SystemZISD::USUBO;
4983 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4987 if (
N->getValueType(1) == MVT::i1)
5013 SDNode *
N =
Op.getNode();
5014 MVT VT =
N->getSimpleValueType(0);
5020 SDValue
LHS =
N->getOperand(0);
5021 SDValue
RHS =
N->getOperand(1);
5022 SDValue Carry =
Op.getOperand(2);
5025 if (VT == MVT::i128) {
5026 unsigned BaseOp = 0;
5027 unsigned FlagOp = 0;
5028 bool IsBorrow =
false;
5029 switch (
Op.getOpcode()) {
5032 BaseOp = SystemZISD::VAC;
5033 FlagOp = SystemZISD::VACCC;
5036 BaseOp = SystemZISD::VSBI;
5037 FlagOp = SystemZISD::VSBCBI;
5056 unsigned BaseOp = 0;
5057 unsigned CCValid = 0;
5058 unsigned CCMask = 0;
5060 switch (
Op.getOpcode()) {
5066 BaseOp = SystemZISD::ADDCARRY;
5074 BaseOp = SystemZISD::SUBCARRY;
5085 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5089 if (
N->getValueType(1) == MVT::i1)
5097 EVT VT =
Op.getValueType();
5099 Op =
Op.getOperand(0);
5120 SDValue Tmp = DAG.
getNode(SystemZISD::VSHL_BY_SCALAR,
DL, VT,
Op, Shift);
5122 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5134 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5148 if (NumSignificantBits == 0)
5154 BitSize = std::min(BitSize, OrigBitSize);
5163 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5165 if (BitSize != OrigBitSize)
5202 EVT RegVT =
Op.getValueType();
5204 return lowerATOMIC_LDST_I128(
Op, DAG);
5205 return lowerLoadF16(
Op, DAG);
5211 if (
Node->getMemoryVT().getSizeInBits() == 128)
5212 return lowerATOMIC_LDST_I128(
Op, DAG);
5213 return lowerStoreF16(
Op, DAG);
5220 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5221 "Only custom lowering i128 or f128.");
5234 EVT WideVT = MVT::i32;
5257 unsigned Opcode)
const {
5261 EVT NarrowVT =
Node->getMemoryVT();
5262 EVT WideVT = MVT::i32;
5263 if (NarrowVT == WideVT)
5267 SDValue ChainIn =
Node->getChain();
5268 SDValue Addr =
Node->getBasePtr();
5270 MachineMemOperand *MMO =
Node->getMemOperand();
5274 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5276 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5278 Src2.getValueType());
5281 SDValue AlignedAddr, BitShift, NegBitShift;
5289 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5292 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5293 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5298 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5299 SDValue
Ops[] = { ChainIn, AlignedAddr,
Src2, BitShift, NegBitShift,
5319 EVT MemVT =
Node->getMemoryVT();
5320 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5322 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5323 assert(Subtarget.hasInterlockedAccess1() &&
5324 "Should have been expanded by AtomicExpand pass.");
5330 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5331 Node->getMemOperand());
5334 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5341 SDValue ChainIn =
Node->getOperand(0);
5342 SDValue Addr =
Node->getOperand(1);
5343 SDValue CmpVal =
Node->getOperand(2);
5344 SDValue SwapVal =
Node->getOperand(3);
5345 MachineMemOperand *MMO =
Node->getMemOperand();
5348 if (
Node->getMemoryVT() == MVT::i128) {
5357 EVT NarrowVT =
Node->getMemoryVT();
5358 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5359 if (NarrowVT == WideVT) {
5360 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5361 SDValue
Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5363 DL, Tys,
Ops, NarrowVT, MMO);
5377 SDValue AlignedAddr, BitShift, NegBitShift;
5381 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5382 SDValue
Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5385 VTList,
Ops, NarrowVT, MMO);
5399SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5422 auto *Regs = Subtarget.getSpecialRegisters();
5425 "in GHC calling convention");
5427 Regs->getStackPointerRegister(),
Op.getValueType());
5433 auto *Regs = Subtarget.getSpecialRegisters();
5434 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5438 "in GHC calling convention");
5440 SDValue Chain =
Op.getOperand(0);
5441 SDValue NewSP =
Op.getOperand(1);
5445 if (StoreBackchain) {
5447 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5448 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5449 MachinePointerInfo());
5452 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5455 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5456 MachinePointerInfo());
5463 bool IsData =
Op.getConstantOperandVal(4);
5466 return Op.getOperand(0);
5469 bool IsWrite =
Op.getConstantOperandVal(2);
5476 Node->getMemoryVT(),
Node->getMemOperand());
5480SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5482 unsigned Opcode, CCValid;
5484 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5495SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5497 unsigned Opcode, CCValid;
5500 if (
Op->getNumValues() == 1)
5502 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5504 SDValue(Node, 0),
getCCResult(DAG, SDValue(Node, 1)));
5507 unsigned Id =
Op.getConstantOperandVal(0);
5509 case Intrinsic::thread_pointer:
5510 return lowerThreadPointer(SDLoc(
Op), DAG);
5512 case Intrinsic::s390_vpdi:
5513 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5514 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5516 case Intrinsic::s390_vperm:
5517 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5518 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5520 case Intrinsic::s390_vuphb:
5521 case Intrinsic::s390_vuphh:
5522 case Intrinsic::s390_vuphf:
5523 case Intrinsic::s390_vuphg:
5524 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5527 case Intrinsic::s390_vuplhb:
5528 case Intrinsic::s390_vuplhh:
5529 case Intrinsic::s390_vuplhf:
5530 case Intrinsic::s390_vuplhg:
5531 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5534 case Intrinsic::s390_vuplb:
5535 case Intrinsic::s390_vuplhw:
5536 case Intrinsic::s390_vuplf:
5537 case Intrinsic::s390_vuplg:
5538 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5541 case Intrinsic::s390_vupllb:
5542 case Intrinsic::s390_vupllh:
5543 case Intrinsic::s390_vupllf:
5544 case Intrinsic::s390_vupllg:
5545 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5548 case Intrinsic::s390_vsumb:
5549 case Intrinsic::s390_vsumh:
5550 case Intrinsic::s390_vsumgh:
5551 case Intrinsic::s390_vsumgf:
5552 case Intrinsic::s390_vsumqf:
5553 case Intrinsic::s390_vsumqg:
5554 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5555 Op.getOperand(1),
Op.getOperand(2));
5557 case Intrinsic::s390_vaq:
5559 Op.getOperand(1),
Op.getOperand(2));
5560 case Intrinsic::s390_vaccb:
5561 case Intrinsic::s390_vacch:
5562 case Intrinsic::s390_vaccf:
5563 case Intrinsic::s390_vaccg:
5564 case Intrinsic::s390_vaccq:
5565 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5566 Op.getOperand(1),
Op.getOperand(2));
5567 case Intrinsic::s390_vacq:
5568 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5569 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5570 case Intrinsic::s390_vacccq:
5571 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5572 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5574 case Intrinsic::s390_vsq:
5576 Op.getOperand(1),
Op.getOperand(2));
5577 case Intrinsic::s390_vscbib:
5578 case Intrinsic::s390_vscbih:
5579 case Intrinsic::s390_vscbif:
5580 case Intrinsic::s390_vscbig:
5581 case Intrinsic::s390_vscbiq:
5582 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5583 Op.getOperand(1),
Op.getOperand(2));
5584 case Intrinsic::s390_vsbiq:
5585 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5586 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5587 case Intrinsic::s390_vsbcbiq:
5588 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5589 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5591 case Intrinsic::s390_vmhb:
5592 case Intrinsic::s390_vmhh:
5593 case Intrinsic::s390_vmhf:
5594 case Intrinsic::s390_vmhg:
5595 case Intrinsic::s390_vmhq:
5597 Op.getOperand(1),
Op.getOperand(2));
5598 case Intrinsic::s390_vmlhb:
5599 case Intrinsic::s390_vmlhh:
5600 case Intrinsic::s390_vmlhf:
5601 case Intrinsic::s390_vmlhg:
5602 case Intrinsic::s390_vmlhq:
5604 Op.getOperand(1),
Op.getOperand(2));
5606 case Intrinsic::s390_vmahb:
5607 case Intrinsic::s390_vmahh:
5608 case Intrinsic::s390_vmahf:
5609 case Intrinsic::s390_vmahg:
5610 case Intrinsic::s390_vmahq:
5611 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5612 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5613 case Intrinsic::s390_vmalhb:
5614 case Intrinsic::s390_vmalhh:
5615 case Intrinsic::s390_vmalhf:
5616 case Intrinsic::s390_vmalhg:
5617 case Intrinsic::s390_vmalhq:
5618 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5619 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5621 case Intrinsic::s390_vmeb:
5622 case Intrinsic::s390_vmeh:
5623 case Intrinsic::s390_vmef:
5624 case Intrinsic::s390_vmeg:
5625 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5626 Op.getOperand(1),
Op.getOperand(2));
5627 case Intrinsic::s390_vmleb:
5628 case Intrinsic::s390_vmleh:
5629 case Intrinsic::s390_vmlef:
5630 case Intrinsic::s390_vmleg:
5631 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5632 Op.getOperand(1),
Op.getOperand(2));
5633 case Intrinsic::s390_vmob:
5634 case Intrinsic::s390_vmoh:
5635 case Intrinsic::s390_vmof:
5636 case Intrinsic::s390_vmog:
5637 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5638 Op.getOperand(1),
Op.getOperand(2));
5639 case Intrinsic::s390_vmlob:
5640 case Intrinsic::s390_vmloh:
5641 case Intrinsic::s390_vmlof:
5642 case Intrinsic::s390_vmlog:
5643 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5644 Op.getOperand(1),
Op.getOperand(2));
5646 case Intrinsic::s390_vmaeb:
5647 case Intrinsic::s390_vmaeh:
5648 case Intrinsic::s390_vmaef:
5649 case Intrinsic::s390_vmaeg:
5651 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5652 Op.getOperand(1),
Op.getOperand(2)),
5654 case Intrinsic::s390_vmaleb:
5655 case Intrinsic::s390_vmaleh:
5656 case Intrinsic::s390_vmalef:
5657 case Intrinsic::s390_vmaleg:
5659 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5660 Op.getOperand(1),
Op.getOperand(2)),
5662 case Intrinsic::s390_vmaob:
5663 case Intrinsic::s390_vmaoh:
5664 case Intrinsic::s390_vmaof:
5665 case Intrinsic::s390_vmaog:
5667 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5668 Op.getOperand(1),
Op.getOperand(2)),
5670 case Intrinsic::s390_vmalob:
5671 case Intrinsic::s390_vmaloh:
5672 case Intrinsic::s390_vmalof:
5673 case Intrinsic::s390_vmalog:
5675 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5676 Op.getOperand(1),
Op.getOperand(2)),
5697 { SystemZISD::MERGE_HIGH, 8,
5698 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5700 { SystemZISD::MERGE_HIGH, 4,
5701 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5703 { SystemZISD::MERGE_HIGH, 2,
5704 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5706 { SystemZISD::MERGE_HIGH, 1,
5707 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5709 { SystemZISD::MERGE_LOW, 8,
5710 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5712 { SystemZISD::MERGE_LOW, 4,
5713 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5715 { SystemZISD::MERGE_LOW, 2,
5716 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5718 { SystemZISD::MERGE_LOW, 1,
5719 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5721 { SystemZISD::PACK, 4,
5722 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5724 { SystemZISD::PACK, 2,
5725 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5727 { SystemZISD::PACK, 1,
5728 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5730 { SystemZISD::PERMUTE_DWORDS, 4,
5731 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5733 { SystemZISD::PERMUTE_DWORDS, 1,
5734 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5748 OpNo0 = OpNo1 = OpNos[1];
5749 }
else if (OpNos[1] < 0) {
5750 OpNo0 = OpNo1 = OpNos[0];
5768 unsigned &OpNo0,
unsigned &OpNo1) {
5769 int OpNos[] = { -1, -1 };
5782 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5784 OpNos[ModelOpNo] = RealOpNo;
5792 unsigned &OpNo0,
unsigned &OpNo1) {
5809 int Elt = Bytes[From];
5812 Transform[From] = -1;
5814 while (
P.Bytes[To] != Elt) {
5819 Transform[From] = To;
5843 Bytes.
resize(NumElements * BytesPerElement, -1);
5844 for (
unsigned I = 0;
I < NumElements; ++
I) {
5845 int Index = VSN->getMaskElt(
I);
5847 for (
unsigned J = 0; J < BytesPerElement; ++J)
5848 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5852 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5855 Bytes.
resize(NumElements * BytesPerElement, -1);
5856 for (
unsigned I = 0;
I < NumElements; ++
I)
5857 for (
unsigned J = 0; J < BytesPerElement; ++J)
5858 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5869 unsigned BytesPerElement,
int &
Base) {
5871 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5872 if (Bytes[Start +
I] >= 0) {
5873 unsigned Elem = Bytes[Start +
I];
5877 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5879 }
else if (
unsigned(
Base) != Elem -
I)
5892 unsigned &StartIndex,
unsigned &OpNo0,
5894 int OpNos[] = { -1, -1 };
5896 for (
unsigned I = 0;
I < 16; ++
I) {
5897 int Index = Bytes[
I];
5903 Shift = ExpectedShift;
5904 else if (Shift != ExpectedShift)
5908 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5910 OpNos[ModelOpNo] = RealOpNo;
5923 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5924 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5932 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5934 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5935 }
else if (
P.Opcode == SystemZISD::PACK) {
5938 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5947 N =
N->getOperand(0);
5950 return Op->getZExtValue() == 0;
5956 for (
unsigned I = 0;
I < Num ;
I++)
5968 for (
unsigned I = 0;
I < 2; ++
I)
5972 unsigned StartIndex, OpNo0, OpNo1;
5974 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5981 if (ZeroVecIdx != UINT32_MAX) {
5982 bool MaskFirst =
true;
5987 if (OpNo == ZeroVecIdx &&
I == 0) {
5992 if (OpNo != ZeroVecIdx && Byte == 0) {
5999 if (ZeroIdx != -1) {
6002 if (Bytes[
I] >= 0) {
6005 if (OpNo == ZeroVecIdx)
6017 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
6020 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
6032 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
6038struct GeneralShuffle {
6039 GeneralShuffle(EVT vt)
6040 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
6042 bool add(SDValue,
unsigned);
6043 SDValue
getNode(SelectionDAG &,
const SDLoc &);
6044 void tryPrepareForUnpack();
6045 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6046 SDValue insertUnpackIfPrepared(SelectionDAG &DAG,
const SDLoc &
DL, SDValue
Op);
6060 unsigned UnpackFromEltSize;
6067void GeneralShuffle::addUndef() {
6069 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6070 Bytes.push_back(-1);
6079bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6085 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6090 if (FromBytesPerElement < BytesPerElement)
6094 (FromBytesPerElement - BytesPerElement));
6097 while (
Op.getNode()) {
6099 Op =
Op.getOperand(0);
6115 }
else if (
Op.isUndef()) {
6124 for (; OpNo <
Ops.size(); ++OpNo)
6125 if (
Ops[OpNo] ==
Op)
6127 if (OpNo ==
Ops.size())
6132 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6133 Bytes.push_back(
Base +
I);
6142 if (
Ops.size() == 0)
6146 tryPrepareForUnpack();
6149 if (
Ops.size() == 1)
6161 unsigned Stride = 1;
6162 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6163 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6173 else if (OpNo ==
I + Stride)
6184 if (NewBytes[J] >= 0) {
6186 "Invalid double permute");
6189 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6195 if (NewBytes[J] >= 0)
6211 unsigned OpNo0, OpNo1;
6215 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6220 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6227 dbgs() <<
Msg.c_str() <<
" { ";
6228 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6229 dbgs() << Bytes[
I] <<
" ";
6237void GeneralShuffle::tryPrepareForUnpack() {
6239 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6244 if (
Ops.size() > 2 &&
6249 UnpackFromEltSize = 1;
6250 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6251 bool MatchUnpack =
true;
6254 unsigned ToEltSize = UnpackFromEltSize * 2;
6255 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6258 if (Bytes[Elt] != -1) {
6260 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6261 MatchUnpack =
false;
6267 if (
Ops.size() == 2) {
6269 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6271 if (SrcBytes[i] == -1)
6273 if (SrcBytes[i] % 16 !=
int(i))
6274 CanUseUnpackHigh =
false;
6276 CanUseUnpackLow =
false;
6277 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6278 UnpackFromEltSize = UINT_MAX;
6282 if (!CanUseUnpackHigh)
6288 if (UnpackFromEltSize > 4)
6291 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6292 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6294 dumpBytes(Bytes,
"Original Bytes vector:"););
6303 Elt += UnpackFromEltSize;
6304 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6305 Bytes[
B] = Bytes[Elt];
6313 Ops.erase(&
Ops[ZeroVecOpNo]);
6315 if (Bytes[
I] >= 0) {
6317 if (OpNo > ZeroVecOpNo)
6328 if (!unpackWasPrepared())
6330 unsigned InBits = UnpackFromEltSize * 8;
6334 unsigned OutBits = InBits * 2;
6337 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6338 : SystemZISD::UNPACKL_HIGH,
6339 DL, OutVT, PackedOp);
6344 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6345 if (!
Op.getOperand(
I).isUndef())
6361 if (
Value.isUndef())
6373 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6376 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6377 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6398 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6414 GeneralShuffle GS(VT);
6416 bool FoundOne =
false;
6417 for (
unsigned I = 0;
I < NumElements; ++
I) {
6420 Op =
Op.getOperand(0);
6423 unsigned Elem =
Op.getConstantOperandVal(1);
6424 if (!GS.add(
Op.getOperand(0), Elem))
6427 }
else if (
Op.isUndef()) {
6441 if (!ResidueOps.
empty()) {
6442 while (ResidueOps.
size() < NumElements)
6444 for (
auto &
Op : GS.Ops) {
6445 if (!
Op.getNode()) {
6451 return GS.getNode(DAG,
SDLoc(BVN));
6454bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6460 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6471 "Handling full vectors only.");
6491 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6503 unsigned int NumElements = Elems.
size();
6504 unsigned int Count = 0;
6505 for (
auto Elem : Elems) {
6506 if (!Elem.isUndef()) {
6509 else if (Elem !=
Single) {
6533 bool AllLoads =
true;
6534 for (
auto Elem : Elems)
6535 if (!isVectorElementLoad(Elem)) {
6541 if (VT == MVT::v2i64 && !AllLoads)
6545 if (VT == MVT::v2f64 && !AllLoads)
6555 if (VT == MVT::v4f32 && !AllLoads)
6559 if (VT == MVT::v8f16 && !AllLoads) {
6568 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6577 unsigned NumConstants = 0;
6578 for (
unsigned I = 0;
I < NumElements; ++
I) {
6579 SDValue Elem = Elems[
I];
6591 SDValue ReplicatedVal;
6592 if (NumConstants > 0) {
6593 for (
unsigned I = 0;
I < NumElements; ++
I)
6604 std::map<const SDNode*, unsigned> UseCounts;
6605 SDNode *LoadMaxUses =
nullptr;
6606 for (
unsigned I = 0;
I < NumElements; ++
I)
6607 if (isVectorElementLoad(Elems[
I])) {
6608 SDNode *Ld = Elems[
I].getNode();
6609 unsigned Count = ++UseCounts[Ld];
6610 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6613 if (LoadMaxUses !=
nullptr) {
6614 ReplicatedVal = SDValue(LoadMaxUses, 0);
6618 unsigned I1 = NumElements / 2 - 1;
6619 unsigned I2 = NumElements - 1;
6620 bool Def1 = !Elems[
I1].isUndef();
6621 bool Def2 = !Elems[I2].isUndef();
6623 SDValue Elem1 = Elems[Def1 ?
I1 : I2];
6624 SDValue Elem2 = Elems[Def2 ? I2 :
I1];
6635 for (
unsigned I = 0;
I < NumElements; ++
I)
6636 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6646 EVT VT =
Op.getValueType();
6648 if (BVN->isConstant()) {
6649 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6667 for (
unsigned I = 0;
I < NumElements; ++
I)
6669 return buildVector(DAG,
DL, VT,
Ops);
6676 EVT VT =
Op.getValueType();
6679 if (VSN->isSplat()) {
6680 SDValue Op0 =
Op.getOperand(0);
6681 unsigned Index = VSN->getSplatIndex();
6683 "Splat index should be defined and in first operand");
6689 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6693 GeneralShuffle
GS(VT);
6694 for (
unsigned I = 0;
I < NumElements; ++
I) {
6695 int Elt = VSN->getMaskElt(
I);
6698 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6699 unsigned(Elt) % NumElements))
6702 return GS.getNode(DAG, SDLoc(VSN));
6717 assert(
Op.getSimpleValueType() == MVT::i64 &&
6718 "Expexted to convert i64 to f16.");
6730 assert(
Op.getSimpleValueType() == MVT::f16 &&
6731 "Expected to convert f16 to i64.");
6745 SDValue Op0 =
Op.getOperand(0);
6746 SDValue Op1 =
Op.getOperand(1);
6747 SDValue Op2 =
Op.getOperand(2);
6748 EVT VT =
Op.getValueType();
6753 if (VT == MVT::v2f64 &&
6777SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6781 SDValue Op0 =
Op.getOperand(0);
6782 SDValue Op1 =
Op.getOperand(1);
6783 EVT VT =
Op.getValueType();
6797 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6805SDValue SystemZTargetLowering::
6807 SDValue PackedOp =
Op.getOperand(0);
6808 EVT OutVT =
Op.getValueType();
6812 unsigned StartOffset = 0;
6819 ArrayRef<int> ShuffleMask = SVN->
getMask();
6824 if (ToBits == 64 && OutNumElts == 2) {
6825 int NumElem = ToBits / FromBits;
6826 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6832 int StartOffsetCandidate = -1;
6833 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6834 if (ShuffleMask[Elt] == -1)
6836 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6837 if (StartOffsetCandidate == -1)
6838 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6839 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6842 StartOffsetCandidate = -1;
6845 if (StartOffsetCandidate != -1) {
6846 StartOffset = StartOffsetCandidate;
6855 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6856 if (StartOffset >= OutNumElts) {
6857 Opcode = SystemZISD::UNPACK_LOW;
6858 StartOffset -= OutNumElts;
6860 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6861 }
while (FromBits != ToBits);
6866SDValue SystemZTargetLowering::
6868 SDValue PackedOp =
Op.getOperand(0);
6870 EVT OutVT =
Op.getValueType();
6874 unsigned NumInPerOut = InNumElts / OutNumElts;
6879 SmallVector<int, 16>
Mask(InNumElts);
6880 unsigned ZeroVecElt = InNumElts;
6881 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6882 unsigned MaskElt = PackedElt * NumInPerOut;
6883 unsigned End = MaskElt + NumInPerOut - 1;
6884 for (; MaskElt <
End; MaskElt++)
6885 Mask[MaskElt] = ZeroVecElt++;
6886 Mask[MaskElt] = PackedElt;
6893 unsigned ByScalar)
const {
6895 SDValue Op0 =
Op.getOperand(0);
6896 SDValue Op1 =
Op.getOperand(1);
6898 EVT VT =
Op.getValueType();
6903 APInt SplatBits, SplatUndef;
6904 unsigned SplatBitSize;
6908 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6909 ElemBitSize,
true) &&
6910 SplatBitSize == ElemBitSize) {
6913 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6916 BitVector UndefElements;
6917 SDValue
Splat = BVN->getSplatValue(&UndefElements);
6922 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6929 if (VSN->isSplat()) {
6930 SDValue VSNOp0 = VSN->getOperand(0);
6931 unsigned Index = VSN->getSplatIndex();
6933 "Splat index should be defined and in first operand");
6940 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6958 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6959 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6960 SDValue Op0 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(0));
6961 SDValue Op1 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(1));
6962 if (ShiftAmt > 120) {
6966 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6970 SmallVector<int, 16>
Mask(16);
6971 for (
unsigned Elt = 0; Elt < 16; Elt++)
6972 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6974 if ((ShiftAmt & 7) == 0)
6978 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6996 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6997 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6998 SDValue Op0 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(0));
6999 SDValue Op1 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(1));
7000 if (ShiftAmt > 120) {
7004 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
7008 SmallVector<int, 16>
Mask(16);
7009 for (
unsigned Elt = 0; Elt < 16; Elt++)
7010 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
7012 if ((ShiftAmt & 7) == 0)
7016 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
7028 MVT DstVT =
Op.getSimpleValueType();
7031 unsigned SrcAS =
N->getSrcAddressSpace();
7033 assert(SrcAS !=
N->getDestAddressSpace() &&
7034 "addrspacecast must be between different address spaces");
7042 }
else if (DstVT == MVT::i32) {
7055 SDValue
In =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
7056 if (
In.getSimpleValueType() != MVT::f16)
7063 SDValue Chain,
bool IsStrict)
const {
7064 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7067 std::tie(Result, Chain) =
7076 bool IsStrict =
Op->isStrictFPOpcode();
7078 MVT VT =
Op.getSimpleValueType();
7079 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7087 if (!Subtarget.hasFPExtension() && !IsSigned)
7098 if (VT == MVT::i128) {
7101 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7111 bool IsStrict =
Op->isStrictFPOpcode();
7113 MVT VT =
Op.getSimpleValueType();
7114 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7115 SDValue Chain = IsStrict ?
Op.getOperand(0) : DAG.
getEntryNode();
7119 if (VT == MVT::f16) {
7126 if (!Subtarget.hasFPExtension() && !IsSigned)
7129 if (InVT == MVT::i128) {
7132 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7141 EVT RegVT =
Op.getValueType();
7142 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7149 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7151 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7152 AtomicLd->getMemOperand());
7155 assert(EVT(RegVT) == Ld->getMemoryVT() &&
"Unhandled f16 load");
7157 Ld->getBasePtr(), Ld->getPointerInfo(), MVT::i16,
7158 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
7172 Shft, AtomicSt->getBasePtr(),
7173 AtomicSt->getMemOperand());
7176 return DAG.
getTruncStore(St->getChain(),
DL, Shft, St->getBasePtr(), MVT::i16,
7177 St->getMemOperand());
7183 MVT ResultVT =
Op.getSimpleValueType();
7184 SDValue Arg =
Op.getOperand(0);
7185 unsigned Check =
Op.getConstantOperandVal(1);
7187 unsigned TDCMask = 0;
7210 SDValue Intr = DAG.
getNode(SystemZISD::TDC,
DL, ResultVT, Arg, TDCMaskV);
7217 SDValue Chain =
Op.getOperand(0);
7222 MachinePointerInfo MPI =
7226 SDValue StoreOps[] = {Chain,
StackPtr};
7228 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7232 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7237 switch (
Op.getOpcode()) {
7239 return lowerFRAMEADDR(
Op, DAG);
7241 return lowerRETURNADDR(
Op, DAG);
7243 return lowerBR_CC(
Op, DAG);
7245 return lowerSELECT_CC(
Op, DAG);
7247 return lowerSETCC(
Op, DAG);
7249 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7251 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7263 return lowerBITCAST(
Op, DAG);
7265 return lowerVASTART(
Op, DAG);
7267 return lowerVACOPY(
Op, DAG);
7269 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7271 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7273 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7275 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7277 return lowerSMUL_LOHI(
Op, DAG);
7279 return lowerUMUL_LOHI(
Op, DAG);
7281 return lowerSDIVREM(
Op, DAG);
7283 return lowerUDIVREM(
Op, DAG);
7288 return lowerXALUO(
Op, DAG);
7291 return lowerUADDSUBO_CARRY(
Op, DAG);
7293 return lowerOR(
Op, DAG);
7295 return lowerCTPOP(
Op, DAG);
7297 return lowerVECREDUCE_ADD(
Op, DAG);
7299 return lowerATOMIC_FENCE(
Op, DAG);
7301 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7303 return lowerATOMIC_STORE(
Op, DAG);
7305 return lowerATOMIC_LOAD(
Op, DAG);
7307 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7309 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7311 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7313 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7315 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7317 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7319 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7321 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7323 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7325 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7327 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7329 return lowerSTACKSAVE(
Op, DAG);
7331 return lowerSTACKRESTORE(
Op, DAG);
7333 return lowerPREFETCH(
Op, DAG);
7335 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7337 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7339 return lowerBUILD_VECTOR(
Op, DAG);
7341 return lowerVECTOR_SHUFFLE(
Op, DAG);
7343 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7345 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7347 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7349 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7351 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7353 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7355 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7357 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7361 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7363 return lowerFSHL(
Op, DAG);
7365 return lowerFSHR(
Op, DAG);
7368 return lowerFP_EXTEND(
Op, DAG);
7373 return lower_FP_TO_INT(
Op, DAG);
7378 return lower_INT_TO_FP(
Op, DAG);
7380 return lowerLoadF16(
Op, DAG);
7382 return lowerStoreF16(
Op, DAG);
7384 return lowerIS_FPCLASS(
Op, DAG);
7386 return lowerGET_ROUNDING(
Op, DAG);
7388 return lowerREADCYCLECOUNTER(
Op, DAG);
7410 &SystemZ::FP128BitRegClass);
7419 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7434 &SystemZ::FP128BitRegClass);
7451 switch (
N->getOpcode()) {
7455 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7458 DL, Tys,
Ops, MVT::i128, MMO);
7461 if (
N->getValueType(0) == MVT::f128)
7475 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7478 DL, Tys,
Ops, MVT::i128, MMO);
7484 MVT::Other, Res), 0);
7496 DL, Tys,
Ops, MVT::i128, MMO);
7510 EVT SrcVT = Src.getValueType();
7511 EVT ResVT =
N->getValueType(0);
7512 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7514 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7515 if (Subtarget.hasVector()) {
7523 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7525 Subtarget.hasVector()
7539 bool IsStrict =
N->isStrictFPOpcode();
7541 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7542 EVT ResVT =
N->getValueType(0);
7544 if (ResVT == MVT::f16) {
7567 bool IsStrict =
N->isStrictFPOpcode();
7569 EVT ResVT =
N->getValueType(0);
7570 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7573 if (InVT == MVT::f16) {
7579 std::tie(InF32, Chain) =
7604bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7605 if (!Subtarget.hasVector())
7619 DAGCombinerInfo &DCI,
7627 unsigned Opcode =
Op.getOpcode();
7630 Op =
Op.getOperand(0);
7632 canTreatAsByteVector(
Op.getValueType())) {
7641 BytesPerElement,
First))
7648 if (Byte % BytesPerElement != 0)
7651 Index = Byte / BytesPerElement;
7655 canTreatAsByteVector(
Op.getValueType())) {
7658 EVT OpVT =
Op.getValueType();
7660 if (OpBytesPerElement < BytesPerElement)
7664 unsigned End = (
Index + 1) * BytesPerElement;
7665 if (
End % OpBytesPerElement != 0)
7668 Op =
Op.getOperand(
End / OpBytesPerElement - 1);
7672 if (!
Op.getValueType().isInteger()) {
7677 DCI.AddToWorklist(
Op.getNode());
7680 if (ResIntVT != ResVT) {
7681 DCI.AddToWorklist(
Op.getNode());
7688 canTreatAsByteVector(
Op.getValueType()) &&
7689 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7691 EVT ExtVT =
Op.getValueType();
7692 EVT OpVT =
Op.getOperand(0).getValueType();
7695 unsigned Byte =
Index * BytesPerElement;
7696 unsigned SubByte =
Byte % ExtBytesPerElement;
7697 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7698 if (SubByte < MinSubByte ||
7699 SubByte + BytesPerElement > ExtBytesPerElement)
7702 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7704 Byte += SubByte - MinSubByte;
7705 if (Byte % BytesPerElement != 0)
7707 Op =
Op.getOperand(0);
7714 if (
Op.getValueType() != VecVT) {
7716 DCI.AddToWorklist(
Op.getNode());
7726SDValue SystemZTargetLowering::combineTruncateExtract(
7733 SDValue Vec =
Op.getOperand(0);
7735 if (canTreatAsByteVector(VecVT)) {
7739 if (BytesPerElement % TruncBytes == 0) {
7745 unsigned Scale = BytesPerElement / TruncBytes;
7746 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7753 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7754 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7762SDValue SystemZTargetLowering::combineZERO_EXTEND(
7763 SDNode *
N, DAGCombinerInfo &DCI)
const {
7765 SelectionDAG &DAG = DCI.DAG;
7766 SDValue N0 =
N->getOperand(0);
7767 EVT VT =
N->getValueType(0);
7768 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7771 if (TrueOp && FalseOp) {
7776 SDValue NewSelect = DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, VT,
Ops);
7779 SDValue TruncSelect =
7781 DCI.CombineTo(N0.
getNode(), TruncSelect);
7824 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7842SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7843 SDNode *
N, DAGCombinerInfo &DCI)
const {
7847 SelectionDAG &DAG = DCI.DAG;
7849 EVT VT =
N->getValueType(0);
7863SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7864 SDNode *
N, DAGCombinerInfo &DCI)
const {
7868 SelectionDAG &DAG = DCI.DAG;
7870 EVT VT =
N->getValueType(0);
7877 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7878 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7894SDValue SystemZTargetLowering::combineMERGE(
7895 SDNode *
N, DAGCombinerInfo &DCI)
const {
7896 SelectionDAG &DAG = DCI.DAG;
7897 unsigned Opcode =
N->getOpcode();
7905 if (Op1 ==
N->getOperand(0))
7910 if (ElemBytes <= 4) {
7911 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7912 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7918 DCI.AddToWorklist(Op1.
getNode());
7920 SDValue
Op = DAG.
getNode(Opcode, SDLoc(
N), OutVT, Op1);
7921 DCI.AddToWorklist(
Op.getNode());
7930 LoPart = HiPart =
nullptr;
7935 if (
Use.getResNo() != 0)
7940 bool IsLoPart =
true;
7965 LoPart = HiPart =
nullptr;
7970 if (
Use.getResNo() != 0)
7976 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7979 switch (
User->getConstantOperandVal(1)) {
7980 case SystemZ::subreg_l64:
7985 case SystemZ::subreg_h64:
7997SDValue SystemZTargetLowering::combineLOAD(
7998 SDNode *
N, DAGCombinerInfo &DCI)
const {
7999 SelectionDAG &DAG = DCI.DAG;
8000 EVT LdVT =
N->getValueType(0);
8004 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
8005 if (PtrVT != LoadNodeVT) {
8009 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
8010 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
8011 LN->getMemOperand());
8021 SDNode *LoPart, *HiPart;
8027 SDValue EltLoad = DAG.
getLoad(
8029 LD->getPointerInfo(),
LD->getBaseAlign(),
8030 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8032 DCI.CombineTo(HiPart, EltLoad,
true);
8036 SDValue EltLoad = DAG.
getLoad(
8039 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
8040 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8042 DCI.CombineTo(LoPart, EltLoad,
true);
8049 DCI.AddToWorklist(Chain.
getNode());
8050 return SDValue(
N, 0);
8064 for (SDUse &Use :
N->uses()) {
8065 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8068 Replicate = SDValue(
Use.getUser(), 0);
8069 }
else if (
Use.getResNo() == 0)
8072 if (!Replicate || OtherUses.
empty())
8078 for (SDNode *U : OtherUses) {
8080 for (SDValue
Op :
U->ops())
8081 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8084 return SDValue(
N, 0);
8087bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8088 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8090 if (Subtarget.hasVectorEnhancements2())
8091 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8103 for (
unsigned i = 0; i < NumElts; ++i) {
8104 if (M[i] < 0)
continue;
8105 if ((
unsigned) M[i] != NumElts - 1 - i)
8113 for (
auto *U : StoredVal->
users()) {
8115 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8174SDValue SystemZTargetLowering::combineSTORE(
8175 SDNode *
N, DAGCombinerInfo &DCI)
const {
8176 SelectionDAG &DAG = DCI.DAG;
8179 EVT MemVT = SN->getMemoryVT();
8183 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8184 if (PtrVT != StoreNodeVT) {
8188 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8189 SN->getPointerInfo(), SN->getBaseAlign(),
8190 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8198 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8200 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8201 DCI.AddToWorklist(
Value.getNode());
8205 SN->getBasePtr(), SN->getMemoryVT(),
8206 SN->getMemOperand());
8217 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8221 if (!SN->isTruncatingStore() &&
8237 Ops, MemVT, SN->getMemOperand());
8240 if (!SN->isTruncatingStore() &&
8243 Subtarget.hasVectorEnhancements2()) {
8245 ArrayRef<int> ShuffleMask = SVN->
getMask();
8253 Ops, MemVT, SN->getMemOperand());
8258 if (!SN->isTruncatingStore() &&
8261 N->getOperand(0).reachesChainWithoutSideEffects(SDValue(Op1.
getNode(), 1))) {
8265 Ops, MemVT, SN->getMemOperand());
8270 SDValue LoPart, HiPart;
8275 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8276 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8278 SN->getChain(),
DL, LoPart,
8280 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8281 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8294 SDValue
Word = SDValue();
8299 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8301 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8305 APInt Val =
C->getAPIntValue();
8308 assert(SN->isTruncatingStore() &&
8309 "Non-truncating store and immediate value does not fit?");
8310 Val = Val.
trunc(TotBytes * 8);
8313 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8314 if (VCI.isVectorConstantLegal(Subtarget) &&
8315 VCI.Opcode == SystemZISD::REPLICATE) {
8323 auto FindReplicatedReg = [&](SDValue MulOp) {
8324 EVT MulVT = MulOp.getValueType();
8325 if (MulOp->getOpcode() ==
ISD::MUL &&
8326 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8328 SDValue
LHS = MulOp->getOperand(0);
8330 WordVT =
LHS->getOperand(0).getValueType();
8337 SystemZVectorConstantInfo VCI(
8339 if (VCI.isVectorConstantLegal(Subtarget) &&
8340 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8341 WordVT == VCI.VecVT.getScalarType())
8353 FindReplicatedReg(SplatVal);
8358 FindReplicatedReg(Op1);
8361 if (Word != SDValue()) {
8363 "Bad type handling");
8367 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8368 SN->getBasePtr(), SN->getMemOperand());
8375SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8376 SDNode *
N, DAGCombinerInfo &DCI)
const {
8377 SelectionDAG &DAG = DCI.DAG;
8380 N->getOperand(0).hasOneUse() &&
8381 Subtarget.hasVectorEnhancements2()) {
8383 ArrayRef<int> ShuffleMask = SVN->
getMask();
8385 SDValue
Load =
N->getOperand(0);
8396 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8400 DCI.CombineTo(
N, ESLoad);
8404 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8407 return SDValue(
N, 0);
8414SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8415 SDNode *
N, DAGCombinerInfo &DCI)
const {
8416 SelectionDAG &DAG = DCI.DAG;
8418 if (!Subtarget.hasVector())
8422 SDValue
Op =
N->getOperand(0);
8424 Op.getValueType().isVector() &&
8425 Op.getOperand(0).getValueType().isVector() &&
8426 Op.getValueType().getVectorNumElements() ==
8427 Op.getOperand(0).getValueType().getVectorNumElements())
8428 Op =
Op.getOperand(0);
8432 EVT VecVT =
Op.getValueType();
8435 Op.getOperand(0),
N->getOperand(1));
8436 DCI.AddToWorklist(
Op.getNode());
8438 if (EltVT !=
N->getValueType(0)) {
8439 DCI.AddToWorklist(
Op.getNode());
8449 if (canTreatAsByteVector(VecVT))
8450 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8451 IndexN->getZExtValue(), DCI,
false);
8456SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8457 SDNode *
N, DAGCombinerInfo &DCI)
const {
8458 SelectionDAG &DAG = DCI.DAG;
8460 if (
N->getOperand(0) ==
N->getOperand(1))
8461 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8471 if (Chain1 == Chain2)
8479SDValue SystemZTargetLowering::combineFP_ROUND(
8480 SDNode *
N, DAGCombinerInfo &DCI)
const {
8482 if (!Subtarget.hasVector())
8491 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8492 SelectionDAG &DAG = DCI.DAG;
8494 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8500 for (
auto *U : Vec->
users()) {
8501 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8503 U->getOperand(0) == Vec &&
8505 U->getConstantOperandVal(1) == 1) {
8506 SDValue OtherRound = SDValue(*
U->user_begin(), 0);
8507 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8508 OtherRound.
getOperand(OpNo) == SDValue(U, 0) &&
8510 SDValue VRound, Chain;
8511 if (
N->isStrictFPOpcode()) {
8515 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8516 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8519 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8521 DCI.AddToWorklist(VRound.
getNode());
8525 DCI.AddToWorklist(Extract1.
getNode());
8531 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8534 N->getVTList(), Extract0, Chain);
8543SDValue SystemZTargetLowering::combineFP_EXTEND(
8544 SDNode *
N, DAGCombinerInfo &DCI)
const {
8546 if (!Subtarget.hasVector())
8555 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8556 SelectionDAG &DAG = DCI.DAG;
8558 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8564 for (
auto *U : Vec->
users()) {
8565 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8567 U->getOperand(0) == Vec &&
8569 U->getConstantOperandVal(1) == 2) {
8570 SDValue OtherExtend = SDValue(*
U->user_begin(), 0);
8571 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8572 OtherExtend.
getOperand(OpNo) == SDValue(U, 0) &&
8574 SDValue VExtend, Chain;
8575 if (
N->isStrictFPOpcode()) {
8579 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8580 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8583 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8585 DCI.AddToWorklist(VExtend.
getNode());
8589 DCI.AddToWorklist(Extract1.
getNode());
8595 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8598 N->getVTList(), Extract0, Chain);
8607SDValue SystemZTargetLowering::combineINT_TO_FP(
8608 SDNode *
N, DAGCombinerInfo &DCI)
const {
8611 SelectionDAG &DAG = DCI.DAG;
8613 unsigned Opcode =
N->getOpcode();
8614 EVT OutVT =
N->getValueType(0);
8616 SDValue
Op =
N->getOperand(0);
8618 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8624 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8625 OutScalarBits <= 64) {
8629 unsigned ExtOpcode =
8631 SDValue ExtOp = DAG.
getNode(ExtOpcode, SDLoc(
N), ExtVT,
Op);
8632 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8637SDValue SystemZTargetLowering::combineFCOPYSIGN(
8638 SDNode *
N, DAGCombinerInfo &DCI)
const {
8639 SelectionDAG &DAG = DCI.DAG;
8640 EVT VT =
N->getValueType(0);
8641 SDValue ValOp =
N->getOperand(0);
8642 SDValue SignOp =
N->getOperand(1);
8653SDValue SystemZTargetLowering::combineBSWAP(
8654 SDNode *
N, DAGCombinerInfo &DCI)
const {
8655 SelectionDAG &DAG = DCI.DAG;
8658 N->getOperand(0).hasOneUse() &&
8659 canLoadStoreByteSwapped(
N->getValueType(0))) {
8660 SDValue
Load =
N->getOperand(0);
8668 EVT LoadVT =
N->getValueType(0);
8669 if (LoadVT == MVT::i16)
8674 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8677 SDValue ResVal = BSLoad;
8678 if (
N->getValueType(0) == MVT::i16)
8683 DCI.CombineTo(
N, ResVal);
8687 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8690 return SDValue(
N, 0);
8694 SDValue
Op =
N->getOperand(0);
8696 Op.getValueType().isVector() &&
8697 Op.getOperand(0).getValueType().isVector() &&
8698 Op.getValueType().getVectorNumElements() ==
8699 Op.getOperand(0).getValueType().getVectorNumElements())
8700 Op =
Op.getOperand(0);
8704 SDValue Vec =
Op.getOperand(0);
8705 SDValue Elt =
Op.getOperand(1);
8706 SDValue
Idx =
Op.getOperand(2);
8712 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8714 EVT VecVT =
N->getValueType(0);
8718 DCI.AddToWorklist(Vec.
getNode());
8722 DCI.AddToWorklist(Elt.
getNode());
8725 DCI.AddToWorklist(Vec.
getNode());
8727 DCI.AddToWorklist(Elt.
getNode());
8735 if (SV &&
Op.hasOneUse()) {
8736 SDValue Op0 =
Op.getOperand(0);
8737 SDValue Op1 =
Op.getOperand(1);
8743 EVT VecVT =
N->getValueType(0);
8746 DCI.AddToWorklist(Op0.
getNode());
8750 DCI.AddToWorklist(Op1.
getNode());
8753 DCI.AddToWorklist(Op0.
getNode());
8755 DCI.AddToWorklist(Op1.
getNode());
8763SDValue SystemZTargetLowering::combineSETCC(
8764 SDNode *
N, DAGCombinerInfo &DCI)
const {
8765 SelectionDAG &DAG = DCI.DAG;
8767 const SDValue
LHS =
N->getOperand(0);
8768 const SDValue
RHS =
N->getOperand(1);
8771 EVT VT =
N->getValueType(0);
8781 Src.getValueType().isFixedLengthVector() &&
8782 Src.getValueType().getScalarType() == MVT::i1) {
8783 EVT CmpVT = Src.getOperand(0).getValueType();
8800 unsigned Depth = 0) {
8808 case SystemZISD::IPM:
8813 case SystemZISD::SELECT_CCMASK: {
8815 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8816 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8819 return std::make_pair(OpCC, OpCCValid);
8824 int CCValidVal = CCValid->getZExtValue();
8825 return std::make_pair(Op4CCReg, CCValidVal);
8836 return std::make_pair(Op0CC, Op0CCValid);
8852 return {Val, Val, Val, Val};
8853 case SystemZISD::IPM: {
8858 for (
auto CC : {0, 1, 2, 3})
8861 return ShiftedCCVals;
8863 case SystemZISD::SELECT_CCMASK: {
8867 if (!CCValid || !CCMask)
8870 int CCValidVal = CCValid->getZExtValue();
8871 int CCMaskVal = CCMask->getZExtValue();
8881 if (TrueSDVals.empty() || FalseSDVals.empty())
8884 for (
auto &CCVal : {0, 1, 2, 3})
8885 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8887 : FalseSDVals[CCVal]);
8888 return MergedSDVals;
8905 if (Op0SDVals.empty() || Op1SDVals.empty())
8908 for (
auto CCVal : {0, 1, 2, 3})
8910 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8911 return BinaryOpSDVals;
8922 auto *CCNode = CCReg.
getNode();
8926 if (CCNode->getOpcode() == SystemZISD::TM) {
8929 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8932 if (!Op0Node || !Op1Node)
8934 auto Op0APVal = Op0Node->getAPIntValue();
8935 auto Op1APVal = Op1Node->getAPIntValue();
8936 auto Result = Op0APVal & Op1APVal;
8937 bool AllOnes = Result == Op1APVal;
8938 bool AllZeros = Result == 0;
8939 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8940 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8944 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8949 if (Op0SDVals.empty() || Op1SDVals.empty())
8952 for (
auto CC : {0, 1, 2, 3}) {
8953 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8957 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8959 NewCCMask &= Op0CCValid;
8962 CCValid = Op0CCValid;
8965 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8972 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8976 if (Op0SDVals.empty() || Op1SDVals.empty())
8980 auto CmpTypeVal = CmpType->getZExtValue();
8981 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8985 if (!Op0Node || !Op1Node)
8987 auto Op0APVal = Op0Node->getAPIntValue();
8988 auto Op1APVal = Op1Node->getAPIntValue();
8990 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8991 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8994 for (
auto CC : {0, 1, 2, 3}) {
8995 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8999 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
9001 NewCCMask &= Op0CCValid;
9004 CCValid = Op0CCValid;
9017 const auto isFlagOutOpCC = [](
const Value *V) {
9019 const Value *RHSVal;
9026 if (CB->isInlineAsm()) {
9028 return IA && IA->getConstraintString().contains(
"{@cc}");
9039 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
9042 return {-1, -1, -1};
9046 DAGCombinerInfo &DCI)
const {
9052 if (!CCValid || !CCMask)
9055 int CCValidVal = CCValid->getZExtValue();
9056 int CCMaskVal = CCMask->getZExtValue();
9063 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9064 CCMaskVal != CCValidVal)
9065 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9069 N->getOperand(3), CCReg);
9073SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9074 SDNode *
N, DAGCombinerInfo &DCI)
const {
9080 if (!CCValid || !CCMask)
9083 int CCValidVal = CCValid->getZExtValue();
9084 int CCMaskVal = CCMask->getZExtValue();
9087 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9091 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9092 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9094 if (Val.getOperand(4) != CCReg)
9101 int CCMaskVal = CCMask->getZExtValue();
9102 for (
auto &CC : {0, 1, 2, 3})
9103 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9111 SDValue
TrueVal =
N->getOperand(0);
9117 if (TrueSDVals.empty())
9118 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9119 if (FalseSDVals.empty())
9120 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9121 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9122 SmallSet<SDValue, 4> MergedSDValsSet;
9124 for (
auto CC : {0, 1, 2, 3}) {
9125 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9126 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9130 if (MergedSDValsSet.
size() == 1)
9131 return *MergedSDValsSet.
begin();
9132 if (MergedSDValsSet.
size() == 2) {
9133 auto BeginIt = MergedSDValsSet.
begin();
9134 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9135 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9138 for (
auto CC : {0, 1, 2, 3}) {
9140 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9141 ? (TrueSDVals[CC] == NewTrueVal)
9142 : (FalseSDVals[CC] == NewTrueVal);
9144 CCMaskVal = NewCCMask;
9145 CCMaskVal &= CCValidVal;
9148 IsCombinedCCReg =
true;
9156 if (CCMaskVal == CCValidVal)
9159 if (IsCombinedCCReg)
9161 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9168SDValue SystemZTargetLowering::combineGET_CCMASK(
9169 SDNode *
N, DAGCombinerInfo &DCI)
const {
9174 if (!CCValid || !CCMask)
9176 int CCValidVal = CCValid->getZExtValue();
9177 int CCMaskVal = CCMask->getZExtValue();
9179 SDValue
Select =
N->getOperand(0);
9182 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9187 if (!SelectCCValid || !SelectCCMask)
9189 int SelectCCValidVal = SelectCCValid->getZExtValue();
9190 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9194 if (!TrueVal || !FalseVal)
9198 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9199 SelectCCMaskVal ^= SelectCCValidVal;
9203 if (SelectCCValidVal & ~CCValidVal)
9205 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9208 return Select->getOperand(4);
9211SDValue SystemZTargetLowering::combineIntDIVREM(
9212 SDNode *
N, DAGCombinerInfo &DCI)
const {
9213 SelectionDAG &DAG = DCI.DAG;
9214 EVT VT =
N->getValueType(0);
9231SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9232 SDNode *
N, DAGCombinerInfo &DCI)
const {
9233 SelectionDAG &DAG = DCI.DAG;
9237 "SRL or SRA node is required here!");
9239 if (!Subtarget.hasVector())
9249 SDValue ShiftOperand =
N->getOperand(0);
9269 if (!IsSignExt && !IsZeroExt)
9275 SDValue MulhRightOp;
9277 unsigned ActiveBits = IsSignExt
9278 ?
Constant->getAPIntValue().getSignificantBits()
9279 :
Constant->getAPIntValue().getActiveBits();
9280 if (ActiveBits > NarrowVTSize)
9296 unsigned ActiveBits = IsSignExt
9297 ?
Constant->getAPIntValue().getSignificantBits()
9298 :
Constant->getAPIntValue().getActiveBits();
9299 if (ActiveBits > NarrowVTSize)
9316 "Cannot have a multiply node with two different operand types.");
9318 "Cannot have an add node with two different operand types.");
9329 if (ShiftAmt != NarrowVTSize)
9333 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9334 NarrowVT == MVT::v4i32 ||
9335 (Subtarget.hasVectorEnhancements3() &&
9336 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9340 SDValue
Result = DAG.
getNode(IsSignExt ? SystemZISD::VMAH : SystemZISD::VMALH,
9342 MulhRightOp, MulhAddOp);
9343 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9354 EVT VT =
Op.getValueType();
9363 Op =
Op.getOperand(0);
9364 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9368 bool CanUseEven =
true, CanUseOdd =
true;
9369 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9370 if (ShuffleMask[Elt] == -1)
9372 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9374 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9377 Op =
Op.getOperand(0);
9379 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9381 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9387 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9391 Op =
Op.getOperand(0);
9393 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9395 unsigned Elem =
Op.getConstantOperandVal(1);
9396 Op =
Op.getOperand(0);
9398 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9400 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9407SDValue SystemZTargetLowering::combineMUL(
9408 SDNode *
N, DAGCombinerInfo &DCI)
const {
9409 SelectionDAG &DAG = DCI.DAG;
9416 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9417 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9422SDValue SystemZTargetLowering::combineINTRINSIC(
9423 SDNode *
N, DAGCombinerInfo &DCI)
const {
9424 SelectionDAG &DAG = DCI.DAG;
9426 unsigned Id =
N->getConstantOperandVal(1);
9430 case Intrinsic::s390_vll:
9431 case Intrinsic::s390_vlrl:
9433 if (
C->getZExtValue() >= 15)
9434 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9435 N->getOperand(3), MachinePointerInfo());
9438 case Intrinsic::s390_vstl:
9439 case Intrinsic::s390_vstrl:
9441 if (
C->getZExtValue() >= 15)
9442 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9443 N->getOperand(4), MachinePointerInfo());
9451 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9458 switch(
N->getOpcode()) {
9463 case SystemZISD::MERGE_HIGH:
9464 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9469 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9479 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9480 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9483 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9484 case ISD::MUL:
return combineMUL(
N, DCI);
9488 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9500 EVT VT =
Op.getValueType();
9503 unsigned Opcode =
Op.getOpcode();
9505 unsigned Id =
Op.getConstantOperandVal(0);
9507 case Intrinsic::s390_vpksh:
9508 case Intrinsic::s390_vpksf:
9509 case Intrinsic::s390_vpksg:
9510 case Intrinsic::s390_vpkshs:
9511 case Intrinsic::s390_vpksfs:
9512 case Intrinsic::s390_vpksgs:
9513 case Intrinsic::s390_vpklsh:
9514 case Intrinsic::s390_vpklsf:
9515 case Intrinsic::s390_vpklsg:
9516 case Intrinsic::s390_vpklshs:
9517 case Intrinsic::s390_vpklsfs:
9518 case Intrinsic::s390_vpklsgs:
9520 SrcDemE = DemandedElts;
9523 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9526 case Intrinsic::s390_vuphb:
9527 case Intrinsic::s390_vuphh:
9528 case Intrinsic::s390_vuphf:
9529 case Intrinsic::s390_vuplhb:
9530 case Intrinsic::s390_vuplhh:
9531 case Intrinsic::s390_vuplhf:
9532 SrcDemE =
APInt(NumElts * 2, 0);
9535 case Intrinsic::s390_vuplb:
9536 case Intrinsic::s390_vuplhw:
9537 case Intrinsic::s390_vuplf:
9538 case Intrinsic::s390_vupllb:
9539 case Intrinsic::s390_vupllh:
9540 case Intrinsic::s390_vupllf:
9541 SrcDemE =
APInt(NumElts * 2, 0);
9544 case Intrinsic::s390_vpdi: {
9546 SrcDemE =
APInt(NumElts, 0);
9547 if (!DemandedElts[OpNo - 1])
9549 unsigned Mask =
Op.getConstantOperandVal(3);
9550 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9552 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9555 case Intrinsic::s390_vsldb: {
9557 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9558 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9559 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9560 unsigned NumSrc0Els = 16 - FirstIdx;
9561 SrcDemE =
APInt(NumElts, 0);
9563 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9566 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9571 case Intrinsic::s390_vperm:
9580 case SystemZISD::JOIN_DWORDS:
9582 SrcDemE =
APInt(1, 1);
9584 case SystemZISD::SELECT_CCMASK:
9585 SrcDemE = DemandedElts;
9596 const APInt &DemandedElts,
9611 const APInt &DemandedElts,
9613 unsigned Depth)
const {
9617 unsigned Tmp0, Tmp1;
9619 Known.Zero.setBitsFrom(2);
9622 EVT VT =
Op.getValueType();
9623 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9626 "KnownBits does not match VT in bitwidth");
9629 "DemandedElts does not match VT number of elements");
9631 unsigned Opcode =
Op.getOpcode();
9633 bool IsLogical =
false;
9634 unsigned Id =
Op.getConstantOperandVal(0);
9636 case Intrinsic::s390_vpksh:
9637 case Intrinsic::s390_vpksf:
9638 case Intrinsic::s390_vpksg:
9639 case Intrinsic::s390_vpkshs:
9640 case Intrinsic::s390_vpksfs:
9641 case Intrinsic::s390_vpksgs:
9642 case Intrinsic::s390_vpklsh:
9643 case Intrinsic::s390_vpklsf:
9644 case Intrinsic::s390_vpklsg:
9645 case Intrinsic::s390_vpklshs:
9646 case Intrinsic::s390_vpklsfs:
9647 case Intrinsic::s390_vpklsgs:
9648 case Intrinsic::s390_vpdi:
9649 case Intrinsic::s390_vsldb:
9650 case Intrinsic::s390_vperm:
9653 case Intrinsic::s390_vuplhb:
9654 case Intrinsic::s390_vuplhh:
9655 case Intrinsic::s390_vuplhf:
9656 case Intrinsic::s390_vupllb:
9657 case Intrinsic::s390_vupllh:
9658 case Intrinsic::s390_vupllf:
9661 case Intrinsic::s390_vuphb:
9662 case Intrinsic::s390_vuphh:
9663 case Intrinsic::s390_vuphf:
9664 case Intrinsic::s390_vuplb:
9665 case Intrinsic::s390_vuplhw:
9666 case Intrinsic::s390_vuplf: {
9681 case SystemZISD::JOIN_DWORDS:
9682 case SystemZISD::SELECT_CCMASK:
9685 case SystemZISD::REPLICATE: {
9708 if (
LHS == 1)
return 1;
9711 if (
RHS == 1)
return 1;
9712 unsigned Common = std::min(
LHS,
RHS);
9713 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9714 EVT VT =
Op.getValueType();
9716 if (SrcBitWidth > VTBits) {
9717 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9718 if (Common > SrcExtraBits)
9719 return (Common - SrcExtraBits);
9722 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9729 unsigned Depth)
const {
9730 if (
Op.getResNo() != 0)
9732 unsigned Opcode =
Op.getOpcode();
9734 unsigned Id =
Op.getConstantOperandVal(0);
9736 case Intrinsic::s390_vpksh:
9737 case Intrinsic::s390_vpksf:
9738 case Intrinsic::s390_vpksg:
9739 case Intrinsic::s390_vpkshs:
9740 case Intrinsic::s390_vpksfs:
9741 case Intrinsic::s390_vpksgs:
9742 case Intrinsic::s390_vpklsh:
9743 case Intrinsic::s390_vpklsf:
9744 case Intrinsic::s390_vpklsg:
9745 case Intrinsic::s390_vpklshs:
9746 case Intrinsic::s390_vpklsfs:
9747 case Intrinsic::s390_vpklsgs:
9748 case Intrinsic::s390_vpdi:
9749 case Intrinsic::s390_vsldb:
9750 case Intrinsic::s390_vperm:
9752 case Intrinsic::s390_vuphb:
9753 case Intrinsic::s390_vuphh:
9754 case Intrinsic::s390_vuphf:
9755 case Intrinsic::s390_vuplb:
9756 case Intrinsic::s390_vuplhw:
9757 case Intrinsic::s390_vuplf: {
9761 EVT VT =
Op.getValueType();
9771 case SystemZISD::SELECT_CCMASK:
9784 switch (
Op->getOpcode()) {
9785 case SystemZISD::PCREL_WRAPPER:
9786 case SystemZISD::PCREL_OFFSET:
9797 "Unexpected stack alignment");
9800 unsigned StackProbeSize =
9803 StackProbeSize &= ~(StackAlign - 1);
9804 return StackProbeSize ? StackProbeSize : StackAlign;
9843 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9845 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9851 if (miI ==
MBB->end()) {
9853 if (Succ->isLiveIn(SystemZ::CC))
9864 switch (
MI.getOpcode()) {
9865 case SystemZ::Select32:
9866 case SystemZ::Select64:
9867 case SystemZ::Select128:
9868 case SystemZ::SelectF32:
9869 case SystemZ::SelectF64:
9870 case SystemZ::SelectF128:
9871 case SystemZ::SelectVR32:
9872 case SystemZ::SelectVR64:
9873 case SystemZ::SelectVR128:
9905 for (
auto *
MI : Selects) {
9906 Register DestReg =
MI->getOperand(0).getReg();
9907 Register TrueReg =
MI->getOperand(1).getReg();
9908 Register FalseReg =
MI->getOperand(2).getReg();
9913 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9916 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9917 TrueReg = It->second.first;
9919 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9920 FalseReg = It->second.second;
9923 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9928 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9939 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9940 assert(TFL->hasReservedCallFrame(MF) &&
9941 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9946 uint32_t NumBytes =
MI.getOperand(0).getImm();
9951 MI.eraseFromParent();
9960 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9962 unsigned CCValid =
MI.getOperand(3).getImm();
9963 unsigned CCMask =
MI.getOperand(4).getImm();
9968 SmallVector<MachineInstr*, 8> Selects;
9969 SmallVector<MachineInstr*, 8> DbgValues;
9975 assert(NextMI.getOperand(3).getImm() == CCValid &&
9976 "Bad CCValid operands since CC was not redefined.");
9977 if (NextMI.getOperand(4).getImm() == CCMask ||
9978 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9984 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9985 NextMI.usesCustomInsertionHook())
9988 for (
auto *SelMI : Selects)
9989 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9993 if (NextMI.isDebugInstr()) {
9995 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9998 }
else if (User || ++
Count > 20)
10002 MachineInstr *LastMI = Selects.back();
10003 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
10005 MachineBasicBlock *StartMBB =
MBB;
10035 for (
auto *SelMI : Selects)
10036 SelMI->eraseFromParent();
10039 for (
auto *DbgMI : DbgValues)
10040 MBB->
splice(InsertPos, StartMBB, DbgMI);
10051 unsigned StoreOpcode,
10052 unsigned STOCOpcode,
10053 bool Invert)
const {
10054 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10056 Register SrcReg =
MI.getOperand(0).getReg();
10057 MachineOperand
Base =
MI.getOperand(1);
10058 int64_t Disp =
MI.getOperand(2).getImm();
10059 Register IndexReg =
MI.getOperand(3).getReg();
10060 unsigned CCValid =
MI.getOperand(4).getImm();
10061 unsigned CCMask =
MI.getOperand(5).getImm();
10064 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10068 MachineMemOperand *MMO =
nullptr;
10069 for (
auto *
I :
MI.memoperands())
10070 if (
I->isStore()) {
10078 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10090 MI.eraseFromParent();
10098 MachineBasicBlock *StartMBB =
MBB;
10104 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10131 MI.eraseFromParent();
10141 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10149 MachineBasicBlock *StartMBB =
MBB;
10167 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10194 MI.eraseFromParent();
10205 bool Invert)
const {
10207 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10214 int64_t Disp =
MI.getOperand(2).getImm();
10216 Register BitShift =
MI.getOperand(4).getReg();
10217 Register NegBitShift =
MI.getOperand(5).getReg();
10218 unsigned BitSize =
MI.getOperand(6).getImm();
10222 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10223 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10224 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10234 MachineBasicBlock *StartMBB =
MBB;
10270 .
addImm(-1U << (32 - BitSize))
10272 }
else if (BinOpcode)
10300 MI.eraseFromParent();
10311 unsigned KeepOldMask)
const {
10313 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10319 int64_t Disp =
MI.getOperand(2).getImm();
10321 Register BitShift =
MI.getOperand(4).getReg();
10322 Register NegBitShift =
MI.getOperand(5).getReg();
10323 unsigned BitSize =
MI.getOperand(6).getImm();
10327 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10328 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10329 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10340 MachineBasicBlock *StartMBB =
MBB;
10408 MI.eraseFromParent();
10418 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10424 int64_t Disp =
MI.getOperand(2).getImm();
10425 Register CmpVal =
MI.getOperand(3).getReg();
10426 Register OrigSwapVal =
MI.getOperand(4).getReg();
10427 Register BitShift =
MI.getOperand(5).getReg();
10428 Register NegBitShift =
MI.getOperand(6).getReg();
10429 int64_t BitSize =
MI.getOperand(7).getImm();
10435 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10436 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10437 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10438 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10450 MachineBasicBlock *StartMBB =
MBB;
10527 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10530 MI.eraseFromParent();
10538 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10543 .
add(
MI.getOperand(1))
10544 .
addImm(SystemZ::subreg_h64)
10545 .
add(
MI.getOperand(2))
10546 .
addImm(SystemZ::subreg_l64);
10547 MI.eraseFromParent();
10556 bool ClearEven)
const {
10558 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10580 MI.eraseFromParent();
10587 unsigned Opcode,
bool IsMemset)
const {
10589 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10594 uint64_t DestDisp =
MI.getOperand(1).getImm();
10599 auto foldDisplIfNeeded = [&](MachineOperand &
Base,
uint64_t &Disp) ->
void {
10602 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10612 SrcDisp =
MI.getOperand(3).getImm();
10614 SrcBase = DestBase;
10615 SrcDisp = DestDisp++;
10616 foldDisplIfNeeded(DestBase, DestDisp);
10619 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10620 bool IsImmForm = LengthMO.
isImm();
10621 bool IsRegForm = !IsImmForm;
10624 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10626 MachineOperand DBase,
uint64_t DDisp,
10628 unsigned Length) ->
void {
10632 if (ByteMO.
isImm())
10647 bool NeedsLoop =
false;
10649 Register LenAdjReg = SystemZ::NoRegister;
10651 ImmLength = LengthMO.
getImm();
10652 ImmLength += IsMemset ? 2 : 1;
10653 if (ImmLength == 0) {
10654 MI.eraseFromParent();
10657 if (Opcode == SystemZ::CLC) {
10658 if (ImmLength > 3 * 256)
10668 }
else if (ImmLength > 6 * 256)
10676 LenAdjReg = LengthMO.
getReg();
10681 MachineBasicBlock *EndMBB =
10682 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10690 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10700 auto loadZeroAddress = [&]() -> MachineOperand {
10705 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10706 DestBase = loadZeroAddress();
10707 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10708 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10710 MachineBasicBlock *StartMBB =
nullptr;
10711 MachineBasicBlock *LoopMBB =
nullptr;
10712 MachineBasicBlock *NextMBB =
nullptr;
10713 MachineBasicBlock *DoneMBB =
nullptr;
10714 MachineBasicBlock *AllDoneMBB =
nullptr;
10718 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10727 RC = &SystemZ::GR64BitRegClass;
10755 MBB = MemsetOneCheckMBB;
10766 MBB = MemsetOneMBB;
10798 if (EndMBB && !ImmLength)
10820 if (!HaveSingleBase)
10827 if (Opcode == SystemZ::MVC)
10854 if (!HaveSingleBase)
10879 Register RemDestReg = HaveSingleBase ? RemSrcReg
10884 if (!HaveSingleBase)
10892 MachineInstrBuilder EXRL_MIB =
10900 if (Opcode != SystemZ::MVC) {
10910 while (ImmLength > 0) {
10914 foldDisplIfNeeded(DestBase, DestDisp);
10915 foldDisplIfNeeded(SrcBase, SrcDisp);
10916 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10917 DestDisp += ThisLength;
10918 SrcDisp += ThisLength;
10919 ImmLength -= ThisLength;
10922 if (EndMBB && ImmLength > 0) {
10938 MI.eraseFromParent();
10945 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10951 assert(Len > 0 && Len <= 256 &&
"Memmove of of unsupported constant length.");
10980 MI.eraseFromParent();
10989 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10993 uint64_t End1Reg =
MI.getOperand(0).getReg();
10994 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10995 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10996 uint64_t CharReg =
MI.getOperand(3).getReg();
11003 MachineBasicBlock *StartMBB =
MBB;
11039 MI.eraseFromParent();
11046 bool NoFloat)
const {
11048 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
11049 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11052 MI.setDesc(
TII->get(Opcode));
11056 uint64_t Control =
MI.getOperand(2).getImm();
11057 static const unsigned GPRControlBit[16] = {
11058 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
11059 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
11061 Control |= GPRControlBit[15];
11062 if (TFI->
hasFP(MF))
11063 Control |= GPRControlBit[11];
11064 MI.getOperand(2).setImm(Control);
11067 for (
int I = 0;
I < 16;
I++) {
11068 if ((Control & GPRControlBit[
I]) == 0) {
11075 if (!NoFloat && (Control & 4) != 0) {
11076 if (Subtarget.hasVector()) {
11093 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11094 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11097 Register SrcReg =
MI.getOperand(0).getReg();
11108 MI.eraseFromParent();
11116 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11117 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11120 Register DstReg =
MI.getOperand(0).getReg();
11121 Register SizeReg =
MI.getOperand(2).getReg();
11123 MachineBasicBlock *StartMBB =
MBB;
11210 MI.eraseFromParent();
11214SDValue SystemZTargetLowering::
11217 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11229 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11234 .
addImm(
MI.getOperand(1).getImm());
11235 MI.eraseFromParent();
11241 switch (
MI.getOpcode()) {
11242 case SystemZ::ADJCALLSTACKDOWN:
11243 case SystemZ::ADJCALLSTACKUP:
11244 return emitAdjCallStack(
MI,
MBB);
11246 case SystemZ::Select32:
11247 case SystemZ::Select64:
11248 case SystemZ::Select128:
11249 case SystemZ::SelectF32:
11250 case SystemZ::SelectF64:
11251 case SystemZ::SelectF128:
11252 case SystemZ::SelectVR32:
11253 case SystemZ::SelectVR64:
11254 case SystemZ::SelectVR128:
11255 return emitSelect(
MI,
MBB);
11257 case SystemZ::CondStore8Mux:
11258 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11259 case SystemZ::CondStore8MuxInv:
11260 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11261 case SystemZ::CondStore16Mux:
11262 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11263 case SystemZ::CondStore16MuxInv:
11264 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11265 case SystemZ::CondStore32Mux:
11266 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11267 case SystemZ::CondStore32MuxInv:
11268 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11269 case SystemZ::CondStore8:
11270 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11271 case SystemZ::CondStore8Inv:
11272 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11273 case SystemZ::CondStore16:
11274 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11275 case SystemZ::CondStore16Inv:
11276 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11277 case SystemZ::CondStore32:
11278 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11279 case SystemZ::CondStore32Inv:
11280 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11281 case SystemZ::CondStore64:
11282 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11283 case SystemZ::CondStore64Inv:
11284 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11285 case SystemZ::CondStoreF32:
11286 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11287 case SystemZ::CondStoreF32Inv:
11288 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11289 case SystemZ::CondStoreF64:
11290 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11291 case SystemZ::CondStoreF64Inv:
11292 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11294 case SystemZ::SCmp128Hi:
11295 return emitICmp128Hi(
MI,
MBB,
false);
11296 case SystemZ::UCmp128Hi:
11297 return emitICmp128Hi(
MI,
MBB,
true);
11299 case SystemZ::PAIR128:
11300 return emitPair128(
MI,
MBB);
11301 case SystemZ::AEXT128:
11302 return emitExt128(
MI,
MBB,
false);
11303 case SystemZ::ZEXT128:
11304 return emitExt128(
MI,
MBB,
true);
11306 case SystemZ::ATOMIC_SWAPW:
11307 return emitAtomicLoadBinary(
MI,
MBB, 0);
11309 case SystemZ::ATOMIC_LOADW_AR:
11310 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11311 case SystemZ::ATOMIC_LOADW_AFI:
11312 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11314 case SystemZ::ATOMIC_LOADW_SR:
11315 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11317 case SystemZ::ATOMIC_LOADW_NR:
11318 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11319 case SystemZ::ATOMIC_LOADW_NILH:
11320 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11322 case SystemZ::ATOMIC_LOADW_OR:
11323 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11324 case SystemZ::ATOMIC_LOADW_OILH:
11325 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11327 case SystemZ::ATOMIC_LOADW_XR:
11328 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11329 case SystemZ::ATOMIC_LOADW_XILF:
11330 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11332 case SystemZ::ATOMIC_LOADW_NRi:
11333 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11334 case SystemZ::ATOMIC_LOADW_NILHi:
11335 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11337 case SystemZ::ATOMIC_LOADW_MIN:
11339 case SystemZ::ATOMIC_LOADW_MAX:
11341 case SystemZ::ATOMIC_LOADW_UMIN:
11343 case SystemZ::ATOMIC_LOADW_UMAX:
11346 case SystemZ::ATOMIC_CMP_SWAPW:
11347 return emitAtomicCmpSwapW(
MI,
MBB);
11348 case SystemZ::MVCImm:
11349 case SystemZ::MVCReg:
11350 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11351 case SystemZ::NCImm:
11352 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11353 case SystemZ::OCImm:
11354 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11355 case SystemZ::XCImm:
11356 case SystemZ::XCReg:
11357 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11358 case SystemZ::CLCImm:
11359 case SystemZ::CLCReg:
11360 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11361 case SystemZ::MemsetImmImm:
11362 case SystemZ::MemsetImmReg:
11363 case SystemZ::MemsetRegImm:
11364 case SystemZ::MemsetRegReg:
11365 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11366 case SystemZ::MemmoveImm:
11367 return emitMemmoveImm(
MI,
MBB);
11368 case SystemZ::CLSTLoop:
11369 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11370 case SystemZ::MVSTLoop:
11371 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11372 case SystemZ::SRSTLoop:
11373 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11374 case SystemZ::TBEGIN:
11375 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11376 case SystemZ::TBEGIN_nofloat:
11377 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11378 case SystemZ::TBEGINC:
11379 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11380 case SystemZ::LTEBRCompare_Pseudo:
11381 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11382 case SystemZ::LTDBRCompare_Pseudo:
11383 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11384 case SystemZ::LTXBRCompare_Pseudo:
11385 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11387 case SystemZ::PROBED_ALLOCA:
11388 return emitProbedAlloca(
MI,
MBB);
11389 case SystemZ::EH_SjLj_SetJmp:
11391 case SystemZ::EH_SjLj_LongJmp:
11394 case TargetOpcode::STACKMAP:
11395 case TargetOpcode::PATCHPOINT:
11398 case SystemZ::MOV_STACKGUARD_DAG:
11399 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11401 case SystemZ::CMP_STACKGUARD_DAG:
11402 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11412SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11413 if (VT == MVT::Untyped)
11414 return &SystemZ::ADDR128BitRegClass;
11440 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11460 EVT VT =
Op.getValueType();
11461 Op =
Op.getOperand(0);
11462 EVT OpVT =
Op.getValueType();
11464 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11475 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11496 if (Attrs.hasRetAttrs())
11497 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11498 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11499 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11502 OS << *FT->getParamType(
I);
11504 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11511bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11512 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11513 if (Itr == IsInternalCache.end())
11514 Itr = IsInternalCache
11515 .insert(std::pair<const Function *, bool>(
11518 return Itr->second;
11521void SystemZTargetLowering::
11529 bool IsInternal =
false;
11530 const Function *CalleeFn =
nullptr;
11533 IsInternal = isInternal(CalleeFn);
11534 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11535 errs() <<
"ERROR: Missing extension attribute of passed "
11536 <<
"value in call to function:\n" <<
"Callee: ";
11537 if (CalleeFn !=
nullptr)
11541 errs() <<
"Caller: ";
11547void SystemZTargetLowering::
11555 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11556 errs() <<
"ERROR: Missing extension attribute of returned "
11557 <<
"value from function:\n";
11565bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11567 if (!Subtarget.isTargetELF())
11576 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11577 MVT VT = Outs[i].VT;
11578 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11581 "Unexpected integer argument VT.");
11582 if (VT == MVT::i32 &&
11593 StringRef GuardMode = M.getStackProtectorGuard();
11596 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)
constexpr bool isScalar() const
Exactly one element.
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()
ElementCount getVectorElementCount() const
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()
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
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
TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
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...
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
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.
virtual TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const
Return the preferred vector type legalization action.
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.
@ End
Run the machine verifier once, at the end of the pipeline.
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.