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())
136 if (!Subtarget.hasVector())
162 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
163 I <= MVT::LAST_FP_VALUETYPE;
189 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
190 I <= MVT::LAST_INTEGER_VALUETYPE;
221 if (Subtarget.hasPopulationCount())
247 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
268 if (!Subtarget.hasVectorEnhancements3()) {
295 if (Subtarget.hasVectorEnhancements3()) {
338 {MVT::i8, MVT::i16, MVT::i32},
Legal);
340 {MVT::i8, MVT::i16},
Legal);
361 if (Subtarget.hasMiscellaneousExtensions4()) {
368 if (Subtarget.hasMiscellaneousExtensions3()) {
453 if (!Subtarget.hasVector()) {
471 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
476 if (Subtarget.hasVectorEnhancements3() &&
477 VT != MVT::v16i8 && VT != MVT::v8i16) {
487 if (Subtarget.hasVectorEnhancements1())
521 if (Subtarget.hasVector()) {
543 if (Subtarget.hasVectorEnhancements2()) {
569 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
583 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
584 I <= MVT::LAST_FP_VALUETYPE;
592 if (Subtarget.hasFPExtension()) {
620 if (Subtarget.hasFPExtension()) {
636 if (Subtarget.hasVector()) {
687 if (Subtarget.hasVectorEnhancements1()) {
694 if (Subtarget.hasVectorEnhancements1()) {
711 for (
MVT Type : {MVT::f64, MVT::v2f64, MVT::f32, MVT::v4f32, MVT::f128}) {
736 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
737 MVT::v4f32, MVT::v2f64 }) {
748 if (!Subtarget.hasVectorEnhancements1()) {
754 if (Subtarget.hasVectorEnhancements1())
764 if (Subtarget.hasVectorEnhancements1()) {
776 if (!Subtarget.hasVector()) {
787 if (Subtarget.isTargetzOS()) {
852 return Subtarget.hasSoftFloat();
873 if (!Subtarget.hasVector() || VT.
getScalarType() == MVT::f16)
883 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
885 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16)) {
886 IntermediateVT = RegisterVT = MVT::v8f16;
887 return NumIntermediates =
891 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
894 if (RegisterVT == MVT::v2i64 && !Subtarget.hasVector()) {
895 IntermediateVT = RegisterVT = MVT::i64;
896 NumIntermediates *= 2;
911 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
915 if (RegisterVT == MVT::v2i64 && !Subtarget.hasVector())
923 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
929 if (RegisterVT == MVT::v2i64 && !Subtarget.hasVector())
956 return Subtarget.hasVectorEnhancements1();
969 if (!Subtarget.hasVector() ||
970 (isFP128 && !Subtarget.hasVectorEnhancements1()))
979 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
986 Opcode = SystemZISD::BYTE_MASK;
992 if (SplatBitSize > 64)
995 auto TryValue = [&](uint64_t
Value) ->
bool {
999 OpVals.push_back(((
unsigned) SignedValue));
1000 Opcode = SystemZISD::REPLICATE;
1006 unsigned Start,
End;
1007 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start,
End)) {
1011 OpVals.push_back(Start - (64 - SplatBitSize));
1012 OpVals.push_back(
End - (64 - SplatBitSize));
1013 Opcode = SystemZISD::ROTATE_MASK;
1025 uint64_t SplatBitsZ = SplatBits.getZExtValue();
1026 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
1038 return TryValue(SplatBitsZ | Middle);
1047 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
1053 unsigned HalfSize = Width / 2;
1058 if (HighValue != LowValue || 8 > HalfSize)
1061 SplatBits = HighValue;
1065 SplatBitSize = Width;
1073 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1077 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1083 bool ForCodeSize)
const {
1085 if (
Imm.isZero() ||
Imm.isNegZero())
1108 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1114 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1167 const int64_t FPOffset = 0;
1188 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1189 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1192 .
addReg(SpecialRegs->getFramePointerRegister())
1200 .
addReg(SpecialRegs->getStackPointerRegister())
1211 .
addReg(SpecialRegs->getStackPointerRegister())
1212 .
addImm(TFL->getBackchainOffset(*MF))
1223 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1227 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1248 MI.eraseFromParent();
1264 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1267 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1274 const int64_t FPOffset = 0;
1286 SpecialRegs->getFramePointerRegister())
1308 SpecialRegs->getStackPointerRegister())
1317 .
addReg(SpecialRegs->getStackPointerRegister())
1318 .
addImm(TFL->getBackchainOffset(*MF))
1324 MI.eraseFromParent();
1331 return MemVT != MVT::v2i64 || Subtarget.hasVector();
1337 return !Subtarget.hasVector();
1367 if (Subtarget.hasInterlockedAccess1() &&
1400 EVT VT =
Y.getValueType();
1403 if (VT == MVT::i32 || VT == MVT::i64)
1404 return Subtarget.hasMiscellaneousExtensions3();
1407 if (VT.
isVector() || VT == MVT::i128)
1408 return Subtarget.hasVector();
1436 bool MVC = Ty->isIntegerTy(8);
1442static AddressingMode
1445 switch (
II->getIntrinsicID()) {
1447 case Intrinsic::memset:
1448 case Intrinsic::memmove:
1449 case Intrinsic::memcpy:
1456 if (SingleUser->getParent() ==
I->getParent()) {
1459 if (
C->getBitWidth() <= 64 &&
1469 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1483 I->getOperand(0)->getType());
1485 bool IsVectorAccess = MemAccessTy->isVectorTy();
1490 Value *DataOp =
I->getOperand(0);
1492 IsVectorAccess =
true;
1498 User *LoadUser = *
I->user_begin();
1500 IsVectorAccess =
true;
1503 if (IsFPAccess || IsVectorAccess)
1522 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1532 return AM.
Scale == 0;
1539 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1540 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1544 "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
1546 if (
Op.isZeroMemset())
1549 const int MVCFastLen = 16;
1552 if (
Op.isMemcpy() &&
Op.size() <= MVCFastLen)
1554 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1558 if ((
Op.size() >= 16 && !
Op.isAligned(
Align(8))) ||
1559 (
Op.size() >= 25 &&
Op.size() <= 31))
1563 Context, MemOps, Limit,
Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1569 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1573 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1575 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1577 return FromBits > ToBits;
1585 return FromBits > ToBits;
1594 if (Constraint.
size() == 1) {
1595 switch (Constraint[0]) {
1621 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1622 switch (Constraint[1]) {
1633 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1643 Value *CallOperandVal = Info.CallOperandVal;
1646 if (!CallOperandVal)
1650 switch (*Constraint) {
1669 if (Subtarget.hasVector())
1700 if (
C->getZExtValue() == 0x7fffffff)
1710static std::pair<unsigned, const TargetRegisterClass *>
1712 const unsigned *Map,
unsigned Size) {
1713 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1714 if (isdigit(Constraint[2])) {
1719 return std::make_pair(Map[Index], RC);
1721 return std::make_pair(0U,
nullptr);
1724std::pair<unsigned, const TargetRegisterClass *>
1727 if (Constraint.
size() == 1) {
1729 switch (Constraint[0]) {
1734 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1736 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1737 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1741 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1742 else if (VT == MVT::i128)
1743 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1744 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1747 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1752 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1754 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1756 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1757 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1762 if (Subtarget.hasVector()) {
1764 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1766 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1768 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1769 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1778 auto getVTSizeInBits = [&VT]() {
1786 if (Constraint[1] ==
'r') {
1787 if (getVTSizeInBits() == 32)
1790 if (getVTSizeInBits() == 128)
1796 if (Constraint[1] ==
'f') {
1798 return std::make_pair(
1800 if (getVTSizeInBits() == 16)
1803 if (getVTSizeInBits() == 32)
1806 if (getVTSizeInBits() == 128)
1812 if (Constraint[1] ==
'v') {
1813 if (!Subtarget.hasVector())
1814 return std::make_pair(
1816 if (getVTSizeInBits() == 16)
1819 if (getVTSizeInBits() == 32)
1822 if (getVTSizeInBits() == 64)
1828 if (Constraint[1] ==
'@') {
1829 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1830 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1843 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1844 : SystemZ::NoRegister)
1846 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1854 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1859 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1874 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1878 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1879 OpInfo.ConstraintVT.getSizeInBits() < 8)
1894 if (Constraint.
size() == 1) {
1895 switch (Constraint[0]) {
1900 Op.getValueType()));
1907 Op.getValueType()));
1914 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1921 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1926 if (
C->getZExtValue() == 0x7fffffff)
1928 Op.getValueType()));
1939#define GET_CALLING_CONV_IMPL
1940#include "SystemZGenCallingConv.inc"
1944 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1950 Type *ToType)
const {
2013 if (BitCastToType == MVT::v2i64)
2037 return DAG.
getNode(SystemZISD::PAIR128,
DL, MVT::v2i64,
Hi,
Lo);
2060 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
2062 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2073 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
2074 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2085template <
class ArgTy>
2088 MVT &PartVT,
unsigned &NumParts) {
2089 if (!Args[
I].Flags.isSplit())
2093 PartVT = ArgLocs[
I].getValVT();
2095 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2096 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2097 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2099 if (Args[PartIdx].Flags.isSplitEnd())
2123 unsigned NumFixedGPRs = 0;
2124 unsigned NumFixedFPRs = 0;
2125 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2138 RC = &SystemZ::GR32BitRegClass;
2142 RC = &SystemZ::GR64BitRegClass;
2146 RC = &SystemZ::FP16BitRegClass;
2150 RC = &SystemZ::FP32BitRegClass;
2154 RC = &SystemZ::FP64BitRegClass;
2158 RC = &SystemZ::FP128BitRegClass;
2167 RC = &SystemZ::VR128BitRegClass;
2181 if (Subtarget.isTargetXPLINK64()) {
2184 ArgSPOffset += XPRegs.getCallFrameSize();
2195 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2199 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2213 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2216 unsigned PartOffset = Ins[
I].PartOffset;
2221 assert(PartOffset &&
"Offset should be non-zero.");
2224 }
else if (Subtarget.isTargetXPLINK64() &&
2227 Ins[
I].ArgVT.isSimple()) {
2232 MVT OrigVT = Ins[
I].ArgVT.getSimpleVT();
2238 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2244 Subtarget.getSpecialRegisters());
2250 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2255 if (IsVarArg && Subtarget.isTargetELF()) {
2268 int64_t RegSaveOffset =
2283 &SystemZ::FP64BitRegClass);
2295 if (Subtarget.isTargetXPLINK64()) {
2300 Subtarget.getSpecialRegisters());
2301 MRI.
addLiveIn(Regs->getADARegister(), ADAvReg);
2313 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2320 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2322 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2329 unsigned Offset,
bool LoadAdr =
false) {
2352 bool LoadAddr =
false;
2374 unsigned ADADelta = 0;
2375 unsigned EPADelta = 8;
2381 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2382 G->getGlobal()->hasPrivateLinkage());
2389 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2435 if (Subtarget.isTargetXPLINK64())
2439 verifyNarrowIntegerArgs_Call(CLI, Outs, &MF.
getFunction(), Callee);
2443 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2462 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2470 unsigned NumParts = 1;
2474 SlotVT = Outs[
I].VT;
2481 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2484 assert(Outs[
I].PartOffset == 0);
2485 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2488 unsigned PartOffset = Outs[
I].PartOffset;
2494 assert(PartOffset &&
"Offset should be non-zero.");
2496 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2498 ArgValue = SpillSlot;
2515 if (!StackPtr.getNode())
2522 else if (VA.
getLocVT() == MVT::f16)
2535 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2539 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2545 if (!MemOpChains.
empty())
2553 if (Subtarget.isTargetXPLINK64()) {
2558 ->getAddressOfCalleeRegister();
2561 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2568 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2571 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2572 }
else if (IsTailCall) {
2575 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2580 for (
const auto &[Reg,
N] : RegsToPass) {
2587 Ops.push_back(Chain);
2588 Ops.push_back(Callee);
2592 for (
const auto &[Reg,
N] : RegsToPass)
2597 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2598 assert(Mask &&
"Missing call preserved mask for calling convention");
2603 Ops.push_back(Glue);
2612 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2622 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2629 VA.getLocVT(), Glue);
2646 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2648 Args.reserve(
Ops.size());
2654 Entry.IsZExt = !Entry.IsSExt;
2655 Args.push_back(Entry);
2666 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2677 const Type *RetTy)
const {
2680 for (
auto &Out : Outs)
2681 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2685 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2686 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2698 verifyNarrowIntegerArgs_Ret(CallConv, Outs, &MF.
getFunction());
2706 if (RetLocs.
empty())
2707 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2716 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2738 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2745 unsigned &CCValid) {
2746 unsigned Id =
Op.getConstantOperandVal(1);
2748 case Intrinsic::s390_tbegin:
2749 Opcode = SystemZISD::TBEGIN;
2753 case Intrinsic::s390_tbegin_nofloat:
2754 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2758 case Intrinsic::s390_tend:
2759 Opcode = SystemZISD::TEND;
2772 unsigned Id =
Op.getConstantOperandVal(0);
2774 case Intrinsic::s390_vpkshs:
2775 case Intrinsic::s390_vpksfs:
2776 case Intrinsic::s390_vpksgs:
2777 Opcode = SystemZISD::PACKS_CC;
2781 case Intrinsic::s390_vpklshs:
2782 case Intrinsic::s390_vpklsfs:
2783 case Intrinsic::s390_vpklsgs:
2784 Opcode = SystemZISD::PACKLS_CC;
2788 case Intrinsic::s390_vceqbs:
2789 case Intrinsic::s390_vceqhs:
2790 case Intrinsic::s390_vceqfs:
2791 case Intrinsic::s390_vceqgs:
2792 case Intrinsic::s390_vceqqs:
2793 Opcode = SystemZISD::VICMPES;
2797 case Intrinsic::s390_vchbs:
2798 case Intrinsic::s390_vchhs:
2799 case Intrinsic::s390_vchfs:
2800 case Intrinsic::s390_vchgs:
2801 case Intrinsic::s390_vchqs:
2802 Opcode = SystemZISD::VICMPHS;
2806 case Intrinsic::s390_vchlbs:
2807 case Intrinsic::s390_vchlhs:
2808 case Intrinsic::s390_vchlfs:
2809 case Intrinsic::s390_vchlgs:
2810 case Intrinsic::s390_vchlqs:
2811 Opcode = SystemZISD::VICMPHLS;
2815 case Intrinsic::s390_vtm:
2816 Opcode = SystemZISD::VTM;
2820 case Intrinsic::s390_vfaebs:
2821 case Intrinsic::s390_vfaehs:
2822 case Intrinsic::s390_vfaefs:
2823 Opcode = SystemZISD::VFAE_CC;
2827 case Intrinsic::s390_vfaezbs:
2828 case Intrinsic::s390_vfaezhs:
2829 case Intrinsic::s390_vfaezfs:
2830 Opcode = SystemZISD::VFAEZ_CC;
2834 case Intrinsic::s390_vfeebs:
2835 case Intrinsic::s390_vfeehs:
2836 case Intrinsic::s390_vfeefs:
2837 Opcode = SystemZISD::VFEE_CC;
2841 case Intrinsic::s390_vfeezbs:
2842 case Intrinsic::s390_vfeezhs:
2843 case Intrinsic::s390_vfeezfs:
2844 Opcode = SystemZISD::VFEEZ_CC;
2848 case Intrinsic::s390_vfenebs:
2849 case Intrinsic::s390_vfenehs:
2850 case Intrinsic::s390_vfenefs:
2851 Opcode = SystemZISD::VFENE_CC;
2855 case Intrinsic::s390_vfenezbs:
2856 case Intrinsic::s390_vfenezhs:
2857 case Intrinsic::s390_vfenezfs:
2858 Opcode = SystemZISD::VFENEZ_CC;
2862 case Intrinsic::s390_vistrbs:
2863 case Intrinsic::s390_vistrhs:
2864 case Intrinsic::s390_vistrfs:
2865 Opcode = SystemZISD::VISTR_CC;
2869 case Intrinsic::s390_vstrcbs:
2870 case Intrinsic::s390_vstrchs:
2871 case Intrinsic::s390_vstrcfs:
2872 Opcode = SystemZISD::VSTRC_CC;
2876 case Intrinsic::s390_vstrczbs:
2877 case Intrinsic::s390_vstrczhs:
2878 case Intrinsic::s390_vstrczfs:
2879 Opcode = SystemZISD::VSTRCZ_CC;
2883 case Intrinsic::s390_vstrsb:
2884 case Intrinsic::s390_vstrsh:
2885 case Intrinsic::s390_vstrsf:
2886 Opcode = SystemZISD::VSTRS_CC;
2890 case Intrinsic::s390_vstrszb:
2891 case Intrinsic::s390_vstrszh:
2892 case Intrinsic::s390_vstrszf:
2893 Opcode = SystemZISD::VSTRSZ_CC;
2897 case Intrinsic::s390_vfcedbs:
2898 case Intrinsic::s390_vfcesbs:
2899 Opcode = SystemZISD::VFCMPES;
2903 case Intrinsic::s390_vfchdbs:
2904 case Intrinsic::s390_vfchsbs:
2905 Opcode = SystemZISD::VFCMPHS;
2909 case Intrinsic::s390_vfchedbs:
2910 case Intrinsic::s390_vfchesbs:
2911 Opcode = SystemZISD::VFCMPHES;
2915 case Intrinsic::s390_vftcidb:
2916 case Intrinsic::s390_vftcisb:
2917 Opcode = SystemZISD::VFTCI;
2921 case Intrinsic::s390_tdc:
2922 Opcode = SystemZISD::TDC;
2935 unsigned NumOps =
Op.getNumOperands();
2938 Ops.push_back(
Op.getOperand(0));
2940 Ops.push_back(
Op.getOperand(
I));
2942 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2956 unsigned NumOps =
Op.getNumOperands();
2962 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2963 "Unhandled intrinsic with f16 operand.");
2966 Ops.push_back(CurrOper);
2980 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2981 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2982 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
3008 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
3011 int64_t
Value = ConstOp1->getSExtValue();
3027 if (!
C.Op0.hasOneUse() ||
3034 unsigned NumBits =
Load->getMemoryVT().getSizeInBits();
3035 if ((NumBits != 8 && NumBits != 16) ||
3036 NumBits !=
Load->getMemoryVT().getStoreSizeInBits())
3042 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
3045 uint64_t Mask = (1 << NumBits) - 1;
3048 int64_t SignedValue = ConstOp1->getSExtValue();
3055 }
else if (NumBits == 8) {
3081 if (
C.Op0.getValueType() != MVT::i32 ||
3082 Load->getExtensionType() != ExtType) {
3084 Load->getBasePtr(),
Load->getPointerInfo(),
3085 Load->getMemoryVT(),
Load->getAlign(),
3086 Load->getMemOperand()->getFlags());
3092 if (
C.Op1.getValueType() != MVT::i32 ||
3093 Value != ConstOp1->getZExtValue())
3103 if (
Load->getMemoryVT() == MVT::i8)
3106 switch (
Load->getExtensionType()) {
3124 if (
C.Op0.isMachineOpcode() &&
3125 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3129 if (
C.Op0.getValueType() == MVT::i128)
3131 if (
C.Op0.getValueType() == MVT::f128)
3143 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3172 unsigned Opcode0 =
C.Op0.getOpcode();
3179 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3194 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3195 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3217 if (C1 && C1->isZero()) {
3236 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3239 if (C1 && C1->getZExtValue() == 32) {
3240 SDValue ShlOp0 =
C.Op0.getOperand(0);
3259 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3262 C.Op1->getAsZExtVal() == 0) {
3264 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3265 C.Op0.getValueSizeInBits().getFixedValue()) {
3266 unsigned Type = L->getExtensionType();
3269 C.Op0 =
C.Op0.getOperand(0);
3285 if (
C.Opcode != SystemZISD::ICMP)
3295 if (!
C.Op1.isMachineOpcode() ||
3296 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3301 C.Opcode = SystemZISD::CMP_STACKGUARD;
3312 uint64_t Amount = Shift->getZExtValue();
3313 if (Amount >=
N.getValueSizeInBits())
3328 unsigned ICmpType) {
3329 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3351 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3357 if (EffectivelyUnsigned && CmpVal <
Low) {
3365 if (CmpVal == Mask) {
3371 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3377 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3385 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3391 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3420 if (
C.Op0.getValueType() == MVT::i128) {
3426 if (Mask && Mask->getAPIntValue() == 0) {
3427 C.Opcode = SystemZISD::VTM;
3444 uint64_t CmpVal = ConstOp1->getZExtValue();
3451 NewC.Op0 =
C.Op0.getOperand(0);
3452 NewC.Op1 =
C.Op0.getOperand(1);
3456 MaskVal = Mask->getZExtValue();
3476 MaskVal = -(CmpVal & -CmpVal);
3485 unsigned NewCCMask, ShiftVal;
3489 (MaskVal >> ShiftVal != 0) &&
3490 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3492 MaskVal >> ShiftVal,
3496 MaskVal >>= ShiftVal;
3500 (MaskVal << ShiftVal != 0) &&
3501 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3503 MaskVal << ShiftVal,
3507 MaskVal <<= ShiftVal;
3516 C.Opcode = SystemZISD::TM;
3518 if (Mask && Mask->getZExtValue() == MaskVal)
3523 C.CCMask = NewCCMask;
3529 if (
C.Opcode != SystemZISD::ICMP)
3531 if (
C.Op0.getValueType() != MVT::i128)
3542 Src = Src.getOperand(0);
3545 unsigned Opcode = 0;
3546 if (Src.hasOneUse()) {
3547 switch (Src.getOpcode()) {
3548 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3549 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3550 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3551 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3552 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3553 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3559 C.Op0 = Src->getOperand(0);
3560 C.Op1 = Src->getOperand(1);
3564 C.CCMask ^=
C.CCValid;
3576 C.Opcode = SystemZISD::VICMPES;
3588 bool Swap =
false, Invert =
false;
3600 C.Opcode = SystemZISD::UCMP128HI;
3602 C.Opcode = SystemZISD::SCMP128HI;
3607 C.CCMask ^=
C.CCValid;
3618 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3621 if ((~
Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3624 C.Op0 =
C.Op0.getOperand(0);
3636 C.CCValid = CCValid;
3639 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3642 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3646 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3649 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3653 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3656 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3659 C.CCMask &= CCValid;
3667 bool IsSignaling =
false) {
3670 unsigned Opcode, CCValid;
3682 Comparison
C(CmpOp0, CmpOp1, Chain);
3684 if (
C.Op0.getValueType().isFloatingPoint()) {
3687 C.Opcode = SystemZISD::FCMP;
3688 else if (!IsSignaling)
3689 C.Opcode = SystemZISD::STRICT_FCMP;
3691 C.Opcode = SystemZISD::STRICT_FCMPS;
3696 C.Opcode = SystemZISD::ICMP;
3732 if (!
C.Op1.getNode()) {
3733 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3734 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3736 switch (
C.Op0.getOpcode()) {
3747 if (
C.Opcode == SystemZISD::ICMP)
3748 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3750 if (
C.Opcode == SystemZISD::TM) {
3753 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3756 if (
C.Opcode == SystemZISD::VICMPES ||
3757 C.Opcode == SystemZISD::VICMPHS ||
3758 C.Opcode == SystemZISD::VICMPHLS ||
3759 C.Opcode == SystemZISD::VFCMPES ||
3760 C.Opcode == SystemZISD::VFCMPHS ||
3761 C.Opcode == SystemZISD::VFCMPHES) {
3762 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3769 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3771 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3780 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3781 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3806 unsigned CCValid,
unsigned CCMask) {
3811 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3889 int Mask[] = { Start, -1, Start + 1, -1 };
3893 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3895 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3909 !Subtarget.hasVectorEnhancements1()) {
3915 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3916 SDValue HRes = DAG.
getNode(Opcode,
DL, VTs, Chain, H0, H1);
3917 SDValue LRes = DAG.
getNode(Opcode,
DL, VTs, Chain, L0, L1);
3918 SDValue Res = DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3923 SDValue
Ops[2] = { Res, NewChain };
3926 SDValue HRes = DAG.
getNode(Opcode,
DL, MVT::v2i64, H0, H1);
3927 SDValue LRes = DAG.
getNode(Opcode,
DL, MVT::v2i64, L0, L1);
3928 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3931 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3932 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3934 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3947 bool IsSignaling)
const {
3950 assert (!IsSignaling || Chain);
3953 bool Invert =
false;
3961 assert(IsFP &&
"Unexpected integer comparison");
3963 DL, VT, CmpOp1, CmpOp0, Chain);
3965 DL, VT, CmpOp0, CmpOp1, Chain);
3969 LT.getValue(1),
GE.getValue(1));
3978 assert(IsFP &&
"Unexpected integer comparison");
3980 DL, VT, CmpOp1, CmpOp0, Chain);
3982 DL, VT, CmpOp0, CmpOp1, Chain);
3986 LT.getValue(1),
GT.getValue(1));
4007 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
4011 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
4016 Chain =
Cmp.getValue(1);
4024 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
4025 SDValue
Ops[2] = {
Cmp, Chain };
4033 SDValue CmpOp0 =
Op.getOperand(0);
4034 SDValue CmpOp1 =
Op.getOperand(1);
4037 EVT VT =
Op.getValueType();
4039 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
4048 bool IsSignaling)
const {
4049 SDValue Chain =
Op.getOperand(0);
4050 SDValue CmpOp0 =
Op.getOperand(1);
4051 SDValue CmpOp1 =
Op.getOperand(2);
4054 EVT VT =
Op.getNode()->getValueType(0);
4056 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
4057 Chain, IsSignaling);
4071 SDValue CmpOp0 =
Op.getOperand(2);
4072 SDValue CmpOp1 =
Op.getOperand(3);
4073 SDValue Dest =
Op.getOperand(4);
4079 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4113 C.CCMask ^=
C.CCValid;
4121 Op = SystemZISD::VICMPE;
4125 Op = SystemZISD::VICMPHL;
4127 Op = SystemZISD::VICMPH;
4142 SDValue CmpOp0 =
Op.getOperand(0);
4143 SDValue CmpOp1 =
Op.getOperand(1);
4144 SDValue TrueOp =
Op.getOperand(2);
4145 SDValue FalseOp =
Op.getOperand(3);
4166 C.Op1->getAsZExtVal() == 0) {
4173 if (Subtarget.hasVectorEnhancements3() &&
4174 C.Opcode == SystemZISD::ICMP &&
4175 C.Op0.getValueType() == MVT::i128 &&
4181 SDValue
Ops[] = {TrueOp, FalseOp,
4185 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4191 const GlobalValue *GV =
Node->getGlobal();
4197 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4219 }
else if (Subtarget.isTargetELF()) {
4224 }
else if (Subtarget.isTargetzOS()) {
4255 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4260 Ops.push_back(Chain);
4262 Node->getValueType(0),
4271 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4272 const uint32_t *
Mask =
4274 assert(Mask &&
"Missing call preserved mask for calling convention");
4278 Ops.push_back(Glue);
4281 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4289SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4313 const GlobalValue *GV =
Node->getGlobal();
4321 SDValue TP = lowerThreadPointer(
DL, DAG);
4328 SystemZConstantPoolValue *CPV =
4337 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4343 SystemZConstantPoolValue *CPV =
4352 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4357 SystemZMachineFunctionInfo* MFI =
4386 SystemZConstantPoolValue *CPV =
4420 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4437 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4442 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4444 MachineFrameInfo &MFI = MF.getFrameInfo();
4448 unsigned Depth =
Op.getConstantOperandVal(0);
4455 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4460 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4466 MachinePointerInfo());
4481 unsigned Depth =
Op.getConstantOperandVal(0);
4486 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4489 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4490 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4491 int Offset = TFL->getReturnAddressOffset(MF);
4495 MachinePointerInfo());
4500 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4502 &SystemZ::GR64BitRegClass);
4509 SDValue
In =
Op.getOperand(0);
4510 EVT InVT =
In.getValueType();
4511 EVT ResVT =
Op.getValueType();
4518 SDValue NewLoad = DAG.
getLoad(ResVT,
DL, LoadN->getChain(),
4519 LoadN->getBasePtr(), LoadN->getMemOperand());
4525 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4527 if (Subtarget.hasHighWord()) {
4531 MVT::i64, SDValue(U64, 0), In);
4539 DL, MVT::f32, Out64);
4541 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4544 MVT::f64, SDValue(U64, 0), In);
4546 if (Subtarget.hasHighWord())
4559 if (Subtarget.isTargetXPLINK64())
4560 return lowerVASTART_XPLINK(
Op, DAG);
4562 return lowerVASTART_ELF(
Op, DAG);
4568 SystemZMachineFunctionInfo *FuncInfo =
4569 MF.
getInfo<SystemZMachineFunctionInfo>();
4579 MachinePointerInfo(SV));
4585 SystemZMachineFunctionInfo *FuncInfo =
4586 MF.
getInfo<SystemZMachineFunctionInfo>();
4589 SDValue Chain =
Op.getOperand(0);
4590 SDValue Addr =
Op.getOperand(1);
4595 const unsigned NumFields = 4;
4596 SDValue Fields[NumFields] = {
4604 SDValue MemOps[NumFields];
4606 for (
unsigned I = 0;
I < NumFields; ++
I) {
4607 SDValue FieldAddr = Addr;
4611 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4612 MachinePointerInfo(SV,
Offset));
4620 SDValue Chain =
Op.getOperand(0);
4621 SDValue DstPtr =
Op.getOperand(1);
4622 SDValue SrcPtr =
Op.getOperand(2);
4632 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4633 MachinePointerInfo(SrcSV));
4637SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4639 if (Subtarget.isTargetXPLINK64())
4640 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4642 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4646SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4648 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4651 SDValue Chain =
Op.getOperand(0);
4652 SDValue
Size =
Op.getOperand(1);
4653 SDValue
Align =
Op.getOperand(2);
4658 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4661 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4662 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4664 SDValue NeededSpace =
Size;
4668 if (ExtraAlignSpace)
4672 bool IsSigned =
false;
4673 bool DoesNotReturn =
false;
4674 bool IsReturnValueUsed =
false;
4675 EVT VT =
Op.getValueType();
4676 SDValue AllocaCall =
4685 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4688 SDValue Glue = AllocaCall.
getValue(2);
4693 SDValue ArgAdjust = DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, PtrMVT);
4697 if (ExtraAlignSpace) {
4709SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4711 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4714 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4716 SDValue Chain =
Op.getOperand(0);
4717 SDValue
Size =
Op.getOperand(1);
4718 SDValue
Align =
Op.getOperand(2);
4723 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4726 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4727 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4730 SDValue NeededSpace =
Size;
4738 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4739 MachinePointerInfo());
4742 if (ExtraAlignSpace)
4749 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4750 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4762 SDValue ArgAdjust = DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4766 if (RequiredAlign > StackAlign) {
4776 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4777 MachinePointerInfo());
4783SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4787 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4792 unsigned Opcode)
const {
4793 EVT VT =
Op.getValueType();
4799 assert(Subtarget.hasMiscellaneousExtensions2());
4804 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4810 EVT VT =
Op.getValueType();
4818 else if (Subtarget.hasMiscellaneousExtensions2())
4823 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4839 SDValue LL =
Op.getOperand(0);
4840 SDValue RL =
Op.getOperand(1);
4858 EVT VT =
Op.getValueType();
4871 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4877 SDValue Op0 =
Op.getOperand(0);
4878 SDValue Op1 =
Op.getOperand(1);
4879 EVT VT =
Op.getValueType();
4899 EVT VT =
Op.getValueType();
4906 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4911 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4914 SDValue
Ops[] = {
Op.getOperand(0),
Op.getOperand(1)};
4921 Known[1].Zero.getZExtValue() };
4923 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4925 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4930 SDValue LowOp =
Ops[
Low];
4962 MVT::i64, HighOp, Low32);
4968 SDNode *
N =
Op.getNode();
4969 SDValue
LHS =
N->getOperand(0);
4970 SDValue
RHS =
N->getOperand(1);
4973 if (
N->getValueType(0) == MVT::i128) {
4974 unsigned BaseOp = 0;
4975 unsigned FlagOp = 0;
4976 bool IsBorrow =
false;
4977 switch (
Op.getOpcode()) {
4981 FlagOp = SystemZISD::VACC;
4985 FlagOp = SystemZISD::VSCBI;
5000 unsigned BaseOp = 0;
5001 unsigned CCValid = 0;
5002 unsigned CCMask = 0;
5004 switch (
Op.getOpcode()) {
5007 BaseOp = SystemZISD::SADDO;
5012 BaseOp = SystemZISD::SSUBO;
5017 BaseOp = SystemZISD::UADDO;
5022 BaseOp = SystemZISD::USUBO;
5028 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
5032 if (
N->getValueType(1) == MVT::i1)
5058 SDNode *
N =
Op.getNode();
5059 MVT VT =
N->getSimpleValueType(0);
5065 SDValue
LHS =
N->getOperand(0);
5066 SDValue
RHS =
N->getOperand(1);
5067 SDValue Carry =
Op.getOperand(2);
5070 if (VT == MVT::i128) {
5071 unsigned BaseOp = 0;
5072 unsigned FlagOp = 0;
5073 bool IsBorrow =
false;
5074 switch (
Op.getOpcode()) {
5077 BaseOp = SystemZISD::VAC;
5078 FlagOp = SystemZISD::VACCC;
5081 BaseOp = SystemZISD::VSBI;
5082 FlagOp = SystemZISD::VSBCBI;
5101 unsigned BaseOp = 0;
5102 unsigned CCValid = 0;
5103 unsigned CCMask = 0;
5105 switch (
Op.getOpcode()) {
5111 BaseOp = SystemZISD::ADDCARRY;
5119 BaseOp = SystemZISD::SUBCARRY;
5130 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5134 if (
N->getValueType(1) == MVT::i1)
5142 EVT VT =
Op.getValueType();
5144 Op =
Op.getOperand(0);
5165 SDValue Tmp = DAG.
getNode(SystemZISD::VSHL_BY_SCALAR,
DL, VT,
Op, Shift);
5167 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5179 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5193 if (NumSignificantBits == 0)
5199 BitSize = std::min(BitSize, OrigBitSize);
5208 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5210 if (BitSize != OrigBitSize)
5247 EVT RegVT =
Op.getValueType();
5249 return lowerATOMIC_LDST_I128(
Op, DAG);
5250 return lowerLoadF16(
Op, DAG);
5256 if (
Node->getMemoryVT().getSizeInBits() == 128)
5257 return lowerATOMIC_LDST_I128(
Op, DAG);
5258 return lowerStoreF16(
Op, DAG);
5265 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5266 "Only custom lowering i128 or f128.");
5279 EVT WideVT = MVT::i32;
5302 unsigned Opcode)
const {
5306 EVT NarrowVT =
Node->getMemoryVT();
5307 EVT WideVT = MVT::i32;
5308 if (NarrowVT == WideVT)
5312 SDValue ChainIn =
Node->getChain();
5313 SDValue Addr =
Node->getBasePtr();
5315 MachineMemOperand *MMO =
Node->getMemOperand();
5319 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5321 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5323 Src2.getValueType());
5326 SDValue AlignedAddr, BitShift, NegBitShift;
5334 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5337 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5338 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5343 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5344 SDValue
Ops[] = { ChainIn, AlignedAddr,
Src2, BitShift, NegBitShift,
5364 EVT MemVT =
Node->getMemoryVT();
5365 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5367 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5368 assert(Subtarget.hasInterlockedAccess1() &&
5369 "Should have been expanded by AtomicExpand pass.");
5375 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5376 Node->getMemOperand());
5379 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5386 SDValue ChainIn =
Node->getOperand(0);
5387 SDValue Addr =
Node->getOperand(1);
5388 SDValue CmpVal =
Node->getOperand(2);
5389 SDValue SwapVal =
Node->getOperand(3);
5390 MachineMemOperand *MMO =
Node->getMemOperand();
5393 if (
Node->getMemoryVT() == MVT::i128) {
5402 EVT NarrowVT =
Node->getMemoryVT();
5403 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5404 if (NarrowVT == WideVT) {
5405 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5406 SDValue
Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5408 DL, Tys,
Ops, NarrowVT, MMO);
5422 SDValue AlignedAddr, BitShift, NegBitShift;
5426 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5427 SDValue
Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5430 VTList,
Ops, NarrowVT, MMO);
5444SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5467 auto *Regs = Subtarget.getSpecialRegisters();
5470 "in GHC calling convention");
5472 Regs->getStackPointerRegister(),
Op.getValueType());
5478 auto *Regs = Subtarget.getSpecialRegisters();
5479 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5483 "in GHC calling convention");
5485 SDValue Chain =
Op.getOperand(0);
5486 SDValue NewSP =
Op.getOperand(1);
5490 if (StoreBackchain) {
5492 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5493 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5494 MachinePointerInfo());
5497 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5500 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5501 MachinePointerInfo());
5508 bool IsData =
Op.getConstantOperandVal(4);
5511 return Op.getOperand(0);
5514 bool IsWrite =
Op.getConstantOperandVal(2);
5521 Node->getMemoryVT(),
Node->getMemOperand());
5525SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5527 unsigned Opcode, CCValid;
5529 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5540SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5542 unsigned Opcode, CCValid;
5545 if (
Op->getNumValues() == 1)
5547 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5549 SDValue(Node, 0),
getCCResult(DAG, SDValue(Node, 1)));
5552 unsigned Id =
Op.getConstantOperandVal(0);
5554 case Intrinsic::thread_pointer:
5555 return lowerThreadPointer(SDLoc(
Op), DAG);
5557 case Intrinsic::s390_vpdi:
5558 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5559 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5561 case Intrinsic::s390_vperm:
5562 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5563 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5565 case Intrinsic::s390_vuphb:
5566 case Intrinsic::s390_vuphh:
5567 case Intrinsic::s390_vuphf:
5568 case Intrinsic::s390_vuphg:
5569 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5572 case Intrinsic::s390_vuplhb:
5573 case Intrinsic::s390_vuplhh:
5574 case Intrinsic::s390_vuplhf:
5575 case Intrinsic::s390_vuplhg:
5576 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5579 case Intrinsic::s390_vuplb:
5580 case Intrinsic::s390_vuplhw:
5581 case Intrinsic::s390_vuplf:
5582 case Intrinsic::s390_vuplg:
5583 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5586 case Intrinsic::s390_vupllb:
5587 case Intrinsic::s390_vupllh:
5588 case Intrinsic::s390_vupllf:
5589 case Intrinsic::s390_vupllg:
5590 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5593 case Intrinsic::s390_vsumb:
5594 case Intrinsic::s390_vsumh:
5595 case Intrinsic::s390_vsumgh:
5596 case Intrinsic::s390_vsumgf:
5597 case Intrinsic::s390_vsumqf:
5598 case Intrinsic::s390_vsumqg:
5599 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5600 Op.getOperand(1),
Op.getOperand(2));
5602 case Intrinsic::s390_vaq:
5604 Op.getOperand(1),
Op.getOperand(2));
5605 case Intrinsic::s390_vaccb:
5606 case Intrinsic::s390_vacch:
5607 case Intrinsic::s390_vaccf:
5608 case Intrinsic::s390_vaccg:
5609 case Intrinsic::s390_vaccq:
5610 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5611 Op.getOperand(1),
Op.getOperand(2));
5612 case Intrinsic::s390_vacq:
5613 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5614 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5615 case Intrinsic::s390_vacccq:
5616 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5617 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5619 case Intrinsic::s390_vsq:
5621 Op.getOperand(1),
Op.getOperand(2));
5622 case Intrinsic::s390_vscbib:
5623 case Intrinsic::s390_vscbih:
5624 case Intrinsic::s390_vscbif:
5625 case Intrinsic::s390_vscbig:
5626 case Intrinsic::s390_vscbiq:
5627 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5628 Op.getOperand(1),
Op.getOperand(2));
5629 case Intrinsic::s390_vsbiq:
5630 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5631 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5632 case Intrinsic::s390_vsbcbiq:
5633 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5634 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5636 case Intrinsic::s390_vmhb:
5637 case Intrinsic::s390_vmhh:
5638 case Intrinsic::s390_vmhf:
5639 case Intrinsic::s390_vmhg:
5640 case Intrinsic::s390_vmhq:
5642 Op.getOperand(1),
Op.getOperand(2));
5643 case Intrinsic::s390_vmlhb:
5644 case Intrinsic::s390_vmlhh:
5645 case Intrinsic::s390_vmlhf:
5646 case Intrinsic::s390_vmlhg:
5647 case Intrinsic::s390_vmlhq:
5649 Op.getOperand(1),
Op.getOperand(2));
5651 case Intrinsic::s390_vmahb:
5652 case Intrinsic::s390_vmahh:
5653 case Intrinsic::s390_vmahf:
5654 case Intrinsic::s390_vmahg:
5655 case Intrinsic::s390_vmahq:
5656 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5657 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5658 case Intrinsic::s390_vmalhb:
5659 case Intrinsic::s390_vmalhh:
5660 case Intrinsic::s390_vmalhf:
5661 case Intrinsic::s390_vmalhg:
5662 case Intrinsic::s390_vmalhq:
5663 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5664 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5666 case Intrinsic::s390_vmeb:
5667 case Intrinsic::s390_vmeh:
5668 case Intrinsic::s390_vmef:
5669 case Intrinsic::s390_vmeg:
5670 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5671 Op.getOperand(1),
Op.getOperand(2));
5672 case Intrinsic::s390_vmleb:
5673 case Intrinsic::s390_vmleh:
5674 case Intrinsic::s390_vmlef:
5675 case Intrinsic::s390_vmleg:
5676 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5677 Op.getOperand(1),
Op.getOperand(2));
5678 case Intrinsic::s390_vmob:
5679 case Intrinsic::s390_vmoh:
5680 case Intrinsic::s390_vmof:
5681 case Intrinsic::s390_vmog:
5682 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5683 Op.getOperand(1),
Op.getOperand(2));
5684 case Intrinsic::s390_vmlob:
5685 case Intrinsic::s390_vmloh:
5686 case Intrinsic::s390_vmlof:
5687 case Intrinsic::s390_vmlog:
5688 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5689 Op.getOperand(1),
Op.getOperand(2));
5691 case Intrinsic::s390_vmaeb:
5692 case Intrinsic::s390_vmaeh:
5693 case Intrinsic::s390_vmaef:
5694 case Intrinsic::s390_vmaeg:
5696 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5697 Op.getOperand(1),
Op.getOperand(2)),
5699 case Intrinsic::s390_vmaleb:
5700 case Intrinsic::s390_vmaleh:
5701 case Intrinsic::s390_vmalef:
5702 case Intrinsic::s390_vmaleg:
5704 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5705 Op.getOperand(1),
Op.getOperand(2)),
5707 case Intrinsic::s390_vmaob:
5708 case Intrinsic::s390_vmaoh:
5709 case Intrinsic::s390_vmaof:
5710 case Intrinsic::s390_vmaog:
5712 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5713 Op.getOperand(1),
Op.getOperand(2)),
5715 case Intrinsic::s390_vmalob:
5716 case Intrinsic::s390_vmaloh:
5717 case Intrinsic::s390_vmalof:
5718 case Intrinsic::s390_vmalog:
5720 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5721 Op.getOperand(1),
Op.getOperand(2)),
5742 { SystemZISD::MERGE_HIGH, 8,
5743 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5745 { SystemZISD::MERGE_HIGH, 4,
5746 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5748 { SystemZISD::MERGE_HIGH, 2,
5749 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5751 { SystemZISD::MERGE_HIGH, 1,
5752 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5754 { SystemZISD::MERGE_LOW, 8,
5755 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5757 { SystemZISD::MERGE_LOW, 4,
5758 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5760 { SystemZISD::MERGE_LOW, 2,
5761 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5763 { SystemZISD::MERGE_LOW, 1,
5764 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5766 { SystemZISD::PACK, 4,
5767 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5769 { SystemZISD::PACK, 2,
5770 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5772 { SystemZISD::PACK, 1,
5773 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5775 { SystemZISD::PERMUTE_DWORDS, 4,
5776 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5778 { SystemZISD::PERMUTE_DWORDS, 1,
5779 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5793 OpNo0 = OpNo1 = OpNos[1];
5794 }
else if (OpNos[1] < 0) {
5795 OpNo0 = OpNo1 = OpNos[0];
5813 unsigned &OpNo0,
unsigned &OpNo1) {
5814 int OpNos[] = { -1, -1 };
5827 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5829 OpNos[ModelOpNo] = RealOpNo;
5837 unsigned &OpNo0,
unsigned &OpNo1) {
5854 int Elt = Bytes[From];
5857 Transform[From] = -1;
5859 while (
P.Bytes[To] != Elt) {
5864 Transform[From] = To;
5888 Bytes.
resize(NumElements * BytesPerElement, -1);
5889 for (
unsigned I = 0;
I < NumElements; ++
I) {
5890 int Index = VSN->getMaskElt(
I);
5892 for (
unsigned J = 0; J < BytesPerElement; ++J)
5893 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5897 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5900 Bytes.
resize(NumElements * BytesPerElement, -1);
5901 for (
unsigned I = 0;
I < NumElements; ++
I)
5902 for (
unsigned J = 0; J < BytesPerElement; ++J)
5903 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5914 unsigned BytesPerElement,
int &
Base) {
5916 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5917 if (Bytes[Start +
I] >= 0) {
5918 unsigned Elem = Bytes[Start +
I];
5922 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5924 }
else if (
unsigned(
Base) != Elem -
I)
5937 unsigned &StartIndex,
unsigned &OpNo0,
5939 int OpNos[] = { -1, -1 };
5941 for (
unsigned I = 0;
I < 16; ++
I) {
5942 int Index = Bytes[
I];
5948 Shift = ExpectedShift;
5949 else if (Shift != ExpectedShift)
5953 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5955 OpNos[ModelOpNo] = RealOpNo;
5968 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5969 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5977 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5979 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5980 }
else if (
P.Opcode == SystemZISD::PACK) {
5983 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5992 N =
N->getOperand(0);
5995 return Op->getZExtValue() == 0;
6001 for (
unsigned I = 0;
I < Num ;
I++)
6013 for (
unsigned I = 0;
I < 2; ++
I)
6017 unsigned StartIndex, OpNo0, OpNo1;
6019 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
6026 if (ZeroVecIdx != UINT32_MAX) {
6027 bool MaskFirst =
true;
6032 if (OpNo == ZeroVecIdx &&
I == 0) {
6037 if (OpNo != ZeroVecIdx && Byte == 0) {
6044 if (ZeroIdx != -1) {
6047 if (Bytes[
I] >= 0) {
6050 if (OpNo == ZeroVecIdx)
6062 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
6065 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
6077 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
6083struct GeneralShuffle {
6084 GeneralShuffle(EVT vt)
6085 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
6087 bool add(SDValue,
unsigned);
6088 SDValue
getNode(SelectionDAG &,
const SDLoc &);
6089 void tryPrepareForUnpack();
6090 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6091 SDValue insertUnpackIfPrepared(SelectionDAG &DAG,
const SDLoc &
DL, SDValue
Op);
6105 unsigned UnpackFromEltSize;
6112void GeneralShuffle::addUndef() {
6114 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6115 Bytes.push_back(-1);
6124bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6130 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6135 if (FromBytesPerElement < BytesPerElement)
6139 (FromBytesPerElement - BytesPerElement));
6142 while (
Op.getNode()) {
6144 Op =
Op.getOperand(0);
6160 }
else if (
Op.isUndef()) {
6169 for (; OpNo <
Ops.size(); ++OpNo)
6170 if (
Ops[OpNo] ==
Op)
6172 if (OpNo ==
Ops.size())
6177 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6178 Bytes.push_back(
Base +
I);
6187 if (
Ops.size() == 0)
6191 tryPrepareForUnpack();
6194 if (
Ops.size() == 1)
6206 unsigned Stride = 1;
6207 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6208 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6218 else if (OpNo ==
I + Stride)
6229 if (NewBytes[J] >= 0) {
6231 "Invalid double permute");
6234 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6240 if (NewBytes[J] >= 0)
6256 unsigned OpNo0, OpNo1;
6260 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6265 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6272 dbgs() <<
Msg.c_str() <<
" { ";
6273 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6274 dbgs() << Bytes[
I] <<
" ";
6282void GeneralShuffle::tryPrepareForUnpack() {
6284 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6289 if (
Ops.size() > 2 &&
6294 UnpackFromEltSize = 1;
6295 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6296 bool MatchUnpack =
true;
6299 unsigned ToEltSize = UnpackFromEltSize * 2;
6300 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6303 if (Bytes[Elt] != -1) {
6305 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6306 MatchUnpack =
false;
6312 if (
Ops.size() == 2) {
6314 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6316 if (SrcBytes[i] == -1)
6318 if (SrcBytes[i] % 16 !=
int(i))
6319 CanUseUnpackHigh =
false;
6321 CanUseUnpackLow =
false;
6322 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6323 UnpackFromEltSize = UINT_MAX;
6327 if (!CanUseUnpackHigh)
6333 if (UnpackFromEltSize > 4)
6336 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6337 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6339 dumpBytes(Bytes,
"Original Bytes vector:"););
6348 Elt += UnpackFromEltSize;
6349 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6350 Bytes[
B] = Bytes[Elt];
6358 Ops.erase(&
Ops[ZeroVecOpNo]);
6360 if (Bytes[
I] >= 0) {
6362 if (OpNo > ZeroVecOpNo)
6373 if (!unpackWasPrepared())
6375 unsigned InBits = UnpackFromEltSize * 8;
6379 unsigned OutBits = InBits * 2;
6382 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6383 : SystemZISD::UNPACKL_HIGH,
6384 DL, OutVT, PackedOp);
6389 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6390 if (!
Op.getOperand(
I).isUndef())
6406 if (
Value.isUndef())
6418 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6421 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6422 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6443 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6459 GeneralShuffle GS(VT);
6461 bool FoundOne =
false;
6462 for (
unsigned I = 0;
I < NumElements; ++
I) {
6465 Op =
Op.getOperand(0);
6468 unsigned Elem =
Op.getConstantOperandVal(1);
6469 if (!GS.add(
Op.getOperand(0), Elem))
6472 }
else if (
Op.isUndef()) {
6486 if (!ResidueOps.
empty()) {
6487 while (ResidueOps.
size() < NumElements)
6489 for (
auto &
Op : GS.Ops) {
6490 if (!
Op.getNode()) {
6496 return GS.getNode(DAG,
SDLoc(BVN));
6499bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6505 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6516 "Handling full vectors only.");
6536 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6548 unsigned int NumElements = Elems.
size();
6549 unsigned int Count = 0;
6550 for (
auto Elem : Elems) {
6551 if (!Elem.isUndef()) {
6554 else if (Elem !=
Single) {
6578 bool AllLoads =
true;
6579 for (
auto Elem : Elems)
6580 if (!isVectorElementLoad(Elem)) {
6586 if (VT == MVT::v2i64 && !AllLoads)
6590 if (VT == MVT::v2f64 && !AllLoads)
6600 if (VT == MVT::v4f32 && !AllLoads)
6604 if (VT == MVT::v8f16 && !AllLoads) {
6613 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6622 unsigned NumConstants = 0;
6623 for (
unsigned I = 0;
I < NumElements; ++
I) {
6624 SDValue Elem = Elems[
I];
6636 SDValue ReplicatedVal;
6637 if (NumConstants > 0) {
6638 for (
unsigned I = 0;
I < NumElements; ++
I)
6649 std::map<const SDNode*, unsigned> UseCounts;
6650 SDNode *LoadMaxUses =
nullptr;
6651 for (
unsigned I = 0;
I < NumElements; ++
I)
6652 if (isVectorElementLoad(Elems[
I])) {
6653 SDNode *Ld = Elems[
I].getNode();
6654 unsigned Count = ++UseCounts[Ld];
6655 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6658 if (LoadMaxUses !=
nullptr) {
6659 ReplicatedVal = SDValue(LoadMaxUses, 0);
6663 unsigned I1 = NumElements / 2 - 1;
6664 unsigned I2 = NumElements - 1;
6665 bool Def1 = !Elems[
I1].isUndef();
6666 bool Def2 = !Elems[I2].isUndef();
6668 SDValue Elem1 = Elems[Def1 ?
I1 : I2];
6669 SDValue Elem2 = Elems[Def2 ? I2 :
I1];
6680 for (
unsigned I = 0;
I < NumElements; ++
I)
6681 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6691 EVT VT =
Op.getValueType();
6693 if (BVN->isConstant()) {
6694 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6712 for (
unsigned I = 0;
I < NumElements; ++
I)
6714 return buildVector(DAG,
DL, VT,
Ops);
6721 EVT VT =
Op.getValueType();
6724 if (VSN->isSplat()) {
6725 SDValue Op0 =
Op.getOperand(0);
6726 unsigned Index = VSN->getSplatIndex();
6728 "Splat index should be defined and in first operand");
6734 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6738 GeneralShuffle
GS(VT);
6739 for (
unsigned I = 0;
I < NumElements; ++
I) {
6740 int Elt = VSN->getMaskElt(
I);
6743 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6744 unsigned(Elt) % NumElements))
6747 return GS.getNode(DAG, SDLoc(VSN));
6762 assert(
Op.getSimpleValueType() == MVT::i64 &&
6763 "Expexted to convert i64 to f16.");
6775 assert(
Op.getSimpleValueType() == MVT::f16 &&
6776 "Expected to convert f16 to i64.");
6795 SDValue Op0 =
Op.getOperand(0);
6796 SDValue Op1 =
Op.getOperand(1);
6797 SDValue Op2 =
Op.getOperand(2);
6798 EVT VT =
Op.getValueType();
6801 if (!Subtarget.hasVector())
6826SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6830 SDValue Op0 =
Op.getOperand(0);
6831 SDValue Op1 =
Op.getOperand(1);
6832 EVT VT =
Op.getValueType();
6839 if (!Subtarget.hasVector())
6845 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6853SDValue SystemZTargetLowering::
6855 SDValue PackedOp =
Op.getOperand(0);
6856 EVT OutVT =
Op.getValueType();
6860 unsigned StartOffset = 0;
6867 ArrayRef<int> ShuffleMask = SVN->
getMask();
6872 if (ToBits == 64 && OutNumElts == 2) {
6873 int NumElem = ToBits / FromBits;
6874 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6880 int StartOffsetCandidate = -1;
6881 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6882 if (ShuffleMask[Elt] == -1)
6884 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6885 if (StartOffsetCandidate == -1)
6886 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6887 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6890 StartOffsetCandidate = -1;
6893 if (StartOffsetCandidate != -1) {
6894 StartOffset = StartOffsetCandidate;
6903 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6904 if (StartOffset >= OutNumElts) {
6905 Opcode = SystemZISD::UNPACK_LOW;
6906 StartOffset -= OutNumElts;
6908 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6909 }
while (FromBits != ToBits);
6914SDValue SystemZTargetLowering::
6916 SDValue PackedOp =
Op.getOperand(0);
6918 EVT OutVT =
Op.getValueType();
6922 unsigned NumInPerOut = InNumElts / OutNumElts;
6927 SmallVector<int, 16>
Mask(InNumElts);
6928 unsigned ZeroVecElt = InNumElts;
6929 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6930 unsigned MaskElt = PackedElt * NumInPerOut;
6931 unsigned End = MaskElt + NumInPerOut - 1;
6932 for (; MaskElt <
End; MaskElt++)
6933 Mask[MaskElt] = ZeroVecElt++;
6934 Mask[MaskElt] = PackedElt;
6941 unsigned ByScalar)
const {
6943 SDValue Op0 =
Op.getOperand(0);
6944 SDValue Op1 =
Op.getOperand(1);
6946 EVT VT =
Op.getValueType();
6951 APInt SplatBits, SplatUndef;
6952 unsigned SplatBitSize;
6956 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6957 ElemBitSize,
true) &&
6958 SplatBitSize == ElemBitSize) {
6961 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6964 BitVector UndefElements;
6965 SDValue
Splat = BVN->getSplatValue(&UndefElements);
6970 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6977 if (VSN->isSplat()) {
6978 SDValue VSNOp0 = VSN->getOperand(0);
6979 unsigned Index = VSN->getSplatIndex();
6981 "Splat index should be defined and in first operand");
6988 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
7006 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
7007 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
7008 SDValue Op0 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(0));
7009 SDValue Op1 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(1));
7010 if (ShiftAmt > 120) {
7014 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
7018 SmallVector<int, 16>
Mask(16);
7019 for (
unsigned Elt = 0; Elt < 16; Elt++)
7020 Mask[Elt] = (ShiftAmt >> 3) + Elt;
7022 if ((ShiftAmt & 7) == 0)
7026 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
7044 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
7045 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
7046 SDValue Op0 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(0));
7047 SDValue Op1 = DAG.
getBitcast(MVT::v16i8,
Op.getOperand(1));
7048 if (ShiftAmt > 120) {
7052 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
7056 SmallVector<int, 16>
Mask(16);
7057 for (
unsigned Elt = 0; Elt < 16; Elt++)
7058 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
7060 if ((ShiftAmt & 7) == 0)
7064 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
7076 MVT DstVT =
Op.getSimpleValueType();
7079 unsigned SrcAS =
N->getSrcAddressSpace();
7081 assert(SrcAS !=
N->getDestAddressSpace() &&
7082 "addrspacecast must be between different address spaces");
7090 }
else if (DstVT == MVT::i32) {
7103 SDValue
In =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
7104 if (
In.getSimpleValueType() != MVT::f16)
7111 SDValue Chain,
bool IsStrict)
const {
7112 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7115 std::tie(Result, Chain) =
7124 bool IsStrict =
Op->isStrictFPOpcode();
7126 MVT VT =
Op.getSimpleValueType();
7127 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7135 if (!Subtarget.hasFPExtension() && !IsSigned)
7146 if (VT == MVT::i128) {
7149 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7159 bool IsStrict =
Op->isStrictFPOpcode();
7161 MVT VT =
Op.getSimpleValueType();
7162 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7163 SDValue Chain = IsStrict ?
Op.getOperand(0) : DAG.
getEntryNode();
7167 if (VT == MVT::f16) {
7174 if (!Subtarget.hasFPExtension() && !IsSigned)
7177 if (InVT == MVT::i128) {
7180 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7189 EVT RegVT =
Op.getValueType();
7190 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7197 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7199 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7200 AtomicLd->getMemOperand());
7203 assert(EVT(RegVT) == Ld->getMemoryVT() &&
"Unhandled f16 load");
7205 Ld->getBasePtr(), Ld->getPointerInfo(), MVT::i16,
7206 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
7220 Shft, AtomicSt->getBasePtr(),
7221 AtomicSt->getMemOperand());
7224 return DAG.
getTruncStore(St->getChain(),
DL, Shft, St->getBasePtr(), MVT::i16,
7225 St->getMemOperand());
7231 MVT ResultVT =
Op.getSimpleValueType();
7232 SDValue Arg =
Op.getOperand(0);
7233 unsigned Check =
Op.getConstantOperandVal(1);
7235 unsigned TDCMask = 0;
7258 SDValue Intr = DAG.
getNode(SystemZISD::TDC,
DL, ResultVT, Arg, TDCMaskV);
7265 SDValue Chain =
Op.getOperand(0);
7270 MachinePointerInfo MPI =
7274 SDValue StoreOps[] = {Chain,
StackPtr};
7276 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7280 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7285 switch (
Op.getOpcode()) {
7287 return lowerFRAMEADDR(
Op, DAG);
7289 return lowerRETURNADDR(
Op, DAG);
7291 return lowerBR_CC(
Op, DAG);
7293 return lowerSELECT_CC(
Op, DAG);
7295 return lowerSETCC(
Op, DAG);
7297 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7299 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7311 return lowerBITCAST(
Op, DAG);
7313 return lowerVASTART(
Op, DAG);
7315 return lowerVACOPY(
Op, DAG);
7317 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7319 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7321 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7323 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7325 return lowerSMUL_LOHI(
Op, DAG);
7327 return lowerUMUL_LOHI(
Op, DAG);
7329 return lowerSDIVREM(
Op, DAG);
7331 return lowerUDIVREM(
Op, DAG);
7336 return lowerXALUO(
Op, DAG);
7339 return lowerUADDSUBO_CARRY(
Op, DAG);
7341 return lowerOR(
Op, DAG);
7343 return lowerCTPOP(
Op, DAG);
7345 return lowerVECREDUCE_ADD(
Op, DAG);
7347 return lowerATOMIC_FENCE(
Op, DAG);
7349 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7351 return lowerATOMIC_STORE(
Op, DAG);
7353 return lowerATOMIC_LOAD(
Op, DAG);
7355 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7357 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7359 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7361 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7363 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7365 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7367 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7369 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7371 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7373 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7375 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7377 return lowerSTACKSAVE(
Op, DAG);
7379 return lowerSTACKRESTORE(
Op, DAG);
7381 return lowerPREFETCH(
Op, DAG);
7383 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7385 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7387 return lowerBUILD_VECTOR(
Op, DAG);
7389 return lowerVECTOR_SHUFFLE(
Op, DAG);
7391 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7393 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7395 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7397 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7399 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7401 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7403 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7405 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7409 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7411 return lowerFSHL(
Op, DAG);
7413 return lowerFSHR(
Op, DAG);
7416 return lowerFP_EXTEND(
Op, DAG);
7421 return lower_FP_TO_INT(
Op, DAG);
7426 return lower_INT_TO_FP(
Op, DAG);
7428 return lowerLoadF16(
Op, DAG);
7430 return lowerStoreF16(
Op, DAG);
7432 return lowerIS_FPCLASS(
Op, DAG);
7434 return lowerGET_ROUNDING(
Op, DAG);
7436 return lowerREADCYCLECOUNTER(
Op, DAG);
7458 &SystemZ::FP128BitRegClass);
7467 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7482 &SystemZ::FP128BitRegClass);
7499 switch (
N->getOpcode()) {
7503 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7506 DL, Tys,
Ops, MVT::i128, MMO);
7509 if (
N->getValueType(0) == MVT::f128)
7523 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7526 DL, Tys,
Ops, MVT::i128, MMO);
7532 MVT::Other, Res), 0);
7544 DL, Tys,
Ops, MVT::i128, MMO);
7558 EVT SrcVT = Src.getValueType();
7559 EVT ResVT =
N->getValueType(0);
7560 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7562 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7563 if (Subtarget.hasVector()) {
7571 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7573 Subtarget.hasVector()
7587 bool IsStrict =
N->isStrictFPOpcode();
7589 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7590 EVT ResVT =
N->getValueType(0);
7592 if (ResVT == MVT::f16) {
7615 bool IsStrict =
N->isStrictFPOpcode();
7617 EVT ResVT =
N->getValueType(0);
7618 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7621 if (InVT == MVT::f16) {
7627 std::tie(InF32, Chain) =
7652bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7653 if (!Subtarget.hasVector())
7667 DAGCombinerInfo &DCI,
7675 unsigned Opcode =
Op.getOpcode();
7678 Op =
Op.getOperand(0);
7680 canTreatAsByteVector(
Op.getValueType())) {
7689 BytesPerElement,
First))
7696 if (Byte % BytesPerElement != 0)
7699 Index = Byte / BytesPerElement;
7703 canTreatAsByteVector(
Op.getValueType())) {
7706 EVT OpVT =
Op.getValueType();
7708 if (OpBytesPerElement < BytesPerElement)
7712 unsigned End = (
Index + 1) * BytesPerElement;
7713 if (
End % OpBytesPerElement != 0)
7716 Op =
Op.getOperand(
End / OpBytesPerElement - 1);
7720 if (!
Op.getValueType().isInteger()) {
7725 DCI.AddToWorklist(
Op.getNode());
7728 if (ResIntVT != ResVT) {
7729 DCI.AddToWorklist(
Op.getNode());
7736 canTreatAsByteVector(
Op.getValueType()) &&
7737 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7739 EVT ExtVT =
Op.getValueType();
7740 EVT OpVT =
Op.getOperand(0).getValueType();
7743 unsigned Byte =
Index * BytesPerElement;
7744 unsigned SubByte =
Byte % ExtBytesPerElement;
7745 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7746 if (SubByte < MinSubByte ||
7747 SubByte + BytesPerElement > ExtBytesPerElement)
7750 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7752 Byte += SubByte - MinSubByte;
7753 if (Byte % BytesPerElement != 0)
7755 Op =
Op.getOperand(0);
7762 if (
Op.getValueType() != VecVT) {
7764 DCI.AddToWorklist(
Op.getNode());
7774SDValue SystemZTargetLowering::combineTruncateExtract(
7781 SDValue Vec =
Op.getOperand(0);
7783 if (canTreatAsByteVector(VecVT)) {
7787 if (BytesPerElement % TruncBytes == 0) {
7793 unsigned Scale = BytesPerElement / TruncBytes;
7794 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7801 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7802 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7810SDValue SystemZTargetLowering::combineZERO_EXTEND(
7811 SDNode *
N, DAGCombinerInfo &DCI)
const {
7813 SelectionDAG &DAG = DCI.DAG;
7814 SDValue N0 =
N->getOperand(0);
7815 EVT VT =
N->getValueType(0);
7816 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7819 if (TrueOp && FalseOp) {
7824 SDValue NewSelect = DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, VT,
Ops);
7827 SDValue TruncSelect =
7829 DCI.CombineTo(N0.
getNode(), TruncSelect);
7872 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7890SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7891 SDNode *
N, DAGCombinerInfo &DCI)
const {
7895 SelectionDAG &DAG = DCI.DAG;
7897 EVT VT =
N->getValueType(0);
7911SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7912 SDNode *
N, DAGCombinerInfo &DCI)
const {
7916 SelectionDAG &DAG = DCI.DAG;
7918 EVT VT =
N->getValueType(0);
7925 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7926 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7942SDValue SystemZTargetLowering::combineMERGE(
7943 SDNode *
N, DAGCombinerInfo &DCI)
const {
7944 SelectionDAG &DAG = DCI.DAG;
7945 unsigned Opcode =
N->getOpcode();
7953 if (Op1 ==
N->getOperand(0))
7958 if (ElemBytes <= 4) {
7959 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7960 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7966 DCI.AddToWorklist(Op1.
getNode());
7968 SDValue
Op = DAG.
getNode(Opcode, SDLoc(
N), OutVT, Op1);
7969 DCI.AddToWorklist(
Op.getNode());
7978 LoPart = HiPart =
nullptr;
7983 if (
Use.getResNo() != 0)
7988 bool IsLoPart =
true;
8013 LoPart = HiPart =
nullptr;
8018 if (
Use.getResNo() != 0)
8024 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
8027 switch (
User->getConstantOperandVal(1)) {
8028 case SystemZ::subreg_l64:
8033 case SystemZ::subreg_h64:
8045SDValue SystemZTargetLowering::combineLOAD(
8046 SDNode *
N, DAGCombinerInfo &DCI)
const {
8047 SelectionDAG &DAG = DCI.DAG;
8048 EVT LdVT =
N->getValueType(0);
8052 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
8053 if (PtrVT != LoadNodeVT) {
8057 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
8058 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
8059 LN->getMemOperand());
8069 SDNode *LoPart, *HiPart;
8075 SDValue EltLoad = DAG.
getLoad(
8077 LD->getPointerInfo(),
LD->getBaseAlign(),
8078 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8080 DCI.CombineTo(HiPart, EltLoad,
true);
8084 SDValue EltLoad = DAG.
getLoad(
8087 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
8088 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8090 DCI.CombineTo(LoPart, EltLoad,
true);
8097 DCI.AddToWorklist(Chain.
getNode());
8098 return SDValue(
N, 0);
8112 for (SDUse &Use :
N->uses()) {
8113 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8116 Replicate = SDValue(
Use.getUser(), 0);
8117 }
else if (
Use.getResNo() == 0)
8120 if (!Replicate || OtherUses.
empty())
8126 for (SDNode *U : OtherUses) {
8128 for (SDValue
Op :
U->ops())
8129 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8132 return SDValue(
N, 0);
8135bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8136 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8138 if (Subtarget.hasVectorEnhancements2())
8139 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8151 for (
unsigned i = 0; i < NumElts; ++i) {
8152 if (M[i] < 0)
continue;
8153 if ((
unsigned) M[i] != NumElts - 1 - i)
8161 for (
auto *U : StoredVal->
users()) {
8163 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8222SDValue SystemZTargetLowering::combineSTORE(
8223 SDNode *
N, DAGCombinerInfo &DCI)
const {
8224 SelectionDAG &DAG = DCI.DAG;
8227 EVT MemVT = SN->getMemoryVT();
8231 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8232 if (PtrVT != StoreNodeVT) {
8236 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8237 SN->getPointerInfo(), SN->getBaseAlign(),
8238 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8246 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8248 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8249 DCI.AddToWorklist(
Value.getNode());
8253 SN->getBasePtr(), SN->getMemoryVT(),
8254 SN->getMemOperand());
8265 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8269 if (!SN->isTruncatingStore() &&
8285 Ops, MemVT, SN->getMemOperand());
8288 if (!SN->isTruncatingStore() &&
8291 Subtarget.hasVectorEnhancements2()) {
8293 ArrayRef<int> ShuffleMask = SVN->
getMask();
8301 Ops, MemVT, SN->getMemOperand());
8306 if (!SN->isTruncatingStore() &&
8309 N->getOperand(0).reachesChainWithoutSideEffects(SDValue(Op1.
getNode(), 1))) {
8313 Ops, MemVT, SN->getMemOperand());
8318 SDValue LoPart, HiPart;
8323 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8324 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8326 SN->getChain(),
DL, LoPart,
8328 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8329 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8342 SDValue
Word = SDValue();
8347 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8349 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8353 APInt Val =
C->getAPIntValue();
8356 assert(SN->isTruncatingStore() &&
8357 "Non-truncating store and immediate value does not fit?");
8358 Val = Val.
trunc(TotBytes * 8);
8361 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8362 if (VCI.isVectorConstantLegal(Subtarget) &&
8363 VCI.Opcode == SystemZISD::REPLICATE) {
8371 auto FindReplicatedReg = [&](SDValue MulOp) {
8372 EVT MulVT = MulOp.getValueType();
8373 if (MulOp->getOpcode() ==
ISD::MUL &&
8374 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8376 SDValue
LHS = MulOp->getOperand(0);
8378 WordVT =
LHS->getOperand(0).getValueType();
8385 SystemZVectorConstantInfo VCI(
8387 if (VCI.isVectorConstantLegal(Subtarget) &&
8388 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8389 WordVT == VCI.VecVT.getScalarType())
8401 FindReplicatedReg(SplatVal);
8406 FindReplicatedReg(Op1);
8409 if (Word != SDValue()) {
8411 "Bad type handling");
8415 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8416 SN->getBasePtr(), SN->getMemOperand());
8423SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8424 SDNode *
N, DAGCombinerInfo &DCI)
const {
8425 SelectionDAG &DAG = DCI.DAG;
8428 N->getOperand(0).hasOneUse() &&
8429 Subtarget.hasVectorEnhancements2()) {
8431 ArrayRef<int> ShuffleMask = SVN->
getMask();
8433 SDValue
Load =
N->getOperand(0);
8444 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8448 DCI.CombineTo(
N, ESLoad);
8452 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8455 return SDValue(
N, 0);
8462SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8463 SDNode *
N, DAGCombinerInfo &DCI)
const {
8464 SelectionDAG &DAG = DCI.DAG;
8466 if (!Subtarget.hasVector())
8470 SDValue
Op =
N->getOperand(0);
8472 Op.getValueType().isVector() &&
8473 Op.getOperand(0).getValueType().isVector() &&
8474 Op.getValueType().getVectorNumElements() ==
8475 Op.getOperand(0).getValueType().getVectorNumElements())
8476 Op =
Op.getOperand(0);
8480 EVT VecVT =
Op.getValueType();
8483 Op.getOperand(0),
N->getOperand(1));
8484 DCI.AddToWorklist(
Op.getNode());
8486 if (EltVT !=
N->getValueType(0)) {
8487 DCI.AddToWorklist(
Op.getNode());
8497 if (canTreatAsByteVector(VecVT))
8498 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8499 IndexN->getZExtValue(), DCI,
false);
8504SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8505 SDNode *
N, DAGCombinerInfo &DCI)
const {
8506 SelectionDAG &DAG = DCI.DAG;
8508 if (
N->getOperand(0) ==
N->getOperand(1))
8509 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8519 if (Chain1 == Chain2)
8527SDValue SystemZTargetLowering::combineFP_ROUND(
8528 SDNode *
N, DAGCombinerInfo &DCI)
const {
8530 if (!Subtarget.hasVector())
8539 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8540 SelectionDAG &DAG = DCI.DAG;
8542 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8548 for (
auto *U : Vec->
users()) {
8549 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8551 U->getOperand(0) == Vec &&
8553 U->getConstantOperandVal(1) == 1) {
8554 SDValue OtherRound = SDValue(*
U->user_begin(), 0);
8555 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8556 OtherRound.
getOperand(OpNo) == SDValue(U, 0) &&
8558 SDValue VRound, Chain;
8559 if (
N->isStrictFPOpcode()) {
8563 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8564 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8567 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8569 DCI.AddToWorklist(VRound.
getNode());
8573 DCI.AddToWorklist(Extract1.
getNode());
8579 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8582 N->getVTList(), Extract0, Chain);
8591SDValue SystemZTargetLowering::combineFP_EXTEND(
8592 SDNode *
N, DAGCombinerInfo &DCI)
const {
8594 if (!Subtarget.hasVector())
8603 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8604 SelectionDAG &DAG = DCI.DAG;
8606 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8612 for (
auto *U : Vec->
users()) {
8613 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8615 U->getOperand(0) == Vec &&
8617 U->getConstantOperandVal(1) == 2) {
8618 SDValue OtherExtend = SDValue(*
U->user_begin(), 0);
8619 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8620 OtherExtend.
getOperand(OpNo) == SDValue(U, 0) &&
8622 SDValue VExtend, Chain;
8623 if (
N->isStrictFPOpcode()) {
8627 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8628 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8631 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8633 DCI.AddToWorklist(VExtend.
getNode());
8637 DCI.AddToWorklist(Extract1.
getNode());
8643 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8646 N->getVTList(), Extract0, Chain);
8655SDValue SystemZTargetLowering::combineINT_TO_FP(
8656 SDNode *
N, DAGCombinerInfo &DCI)
const {
8659 SelectionDAG &DAG = DCI.DAG;
8661 unsigned Opcode =
N->getOpcode();
8662 EVT OutVT =
N->getValueType(0);
8664 SDValue
Op =
N->getOperand(0);
8666 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8672 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8673 OutScalarBits <= 64) {
8677 unsigned ExtOpcode =
8679 SDValue ExtOp = DAG.
getNode(ExtOpcode, SDLoc(
N), ExtVT,
Op);
8680 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8685SDValue SystemZTargetLowering::combineFCOPYSIGN(
8686 SDNode *
N, DAGCombinerInfo &DCI)
const {
8687 SelectionDAG &DAG = DCI.DAG;
8688 EVT VT =
N->getValueType(0);
8689 SDValue ValOp =
N->getOperand(0);
8690 SDValue SignOp =
N->getOperand(1);
8701SDValue SystemZTargetLowering::combineBSWAP(
8702 SDNode *
N, DAGCombinerInfo &DCI)
const {
8703 SelectionDAG &DAG = DCI.DAG;
8706 N->getOperand(0).hasOneUse() &&
8707 canLoadStoreByteSwapped(
N->getValueType(0))) {
8708 SDValue
Load =
N->getOperand(0);
8716 EVT LoadVT =
N->getValueType(0);
8717 if (LoadVT == MVT::i16)
8722 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8725 SDValue ResVal = BSLoad;
8726 if (
N->getValueType(0) == MVT::i16)
8731 DCI.CombineTo(
N, ResVal);
8735 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8738 return SDValue(
N, 0);
8742 SDValue
Op =
N->getOperand(0);
8744 Op.getValueType().isVector() &&
8745 Op.getOperand(0).getValueType().isVector() &&
8746 Op.getValueType().getVectorNumElements() ==
8747 Op.getOperand(0).getValueType().getVectorNumElements())
8748 Op =
Op.getOperand(0);
8752 SDValue Vec =
Op.getOperand(0);
8753 SDValue Elt =
Op.getOperand(1);
8754 SDValue
Idx =
Op.getOperand(2);
8760 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8762 EVT VecVT =
N->getValueType(0);
8766 DCI.AddToWorklist(Vec.
getNode());
8770 DCI.AddToWorklist(Elt.
getNode());
8773 DCI.AddToWorklist(Vec.
getNode());
8775 DCI.AddToWorklist(Elt.
getNode());
8783 if (SV &&
Op.hasOneUse()) {
8784 SDValue Op0 =
Op.getOperand(0);
8785 SDValue Op1 =
Op.getOperand(1);
8791 EVT VecVT =
N->getValueType(0);
8794 DCI.AddToWorklist(Op0.
getNode());
8798 DCI.AddToWorklist(Op1.
getNode());
8801 DCI.AddToWorklist(Op0.
getNode());
8803 DCI.AddToWorklist(Op1.
getNode());
8811SDValue SystemZTargetLowering::combineSETCC(
8812 SDNode *
N, DAGCombinerInfo &DCI)
const {
8813 SelectionDAG &DAG = DCI.DAG;
8815 const SDValue
LHS =
N->getOperand(0);
8816 const SDValue
RHS =
N->getOperand(1);
8819 EVT VT =
N->getValueType(0);
8829 Src.getValueType().isFixedLengthVector() &&
8830 Src.getValueType().getScalarType() == MVT::i1) {
8831 EVT CmpVT = Src.getOperand(0).getValueType();
8848 unsigned Depth = 0) {
8856 case SystemZISD::IPM:
8861 case SystemZISD::SELECT_CCMASK: {
8863 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8864 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8867 return std::make_pair(OpCC, OpCCValid);
8872 int CCValidVal = CCValid->getZExtValue();
8873 return std::make_pair(Op4CCReg, CCValidVal);
8884 return std::make_pair(Op0CC, Op0CCValid);
8900 return {Val, Val, Val, Val};
8901 case SystemZISD::IPM: {
8906 for (
auto CC : {0, 1, 2, 3})
8909 return ShiftedCCVals;
8911 case SystemZISD::SELECT_CCMASK: {
8915 if (!CCValid || !CCMask)
8918 int CCValidVal = CCValid->getZExtValue();
8919 int CCMaskVal = CCMask->getZExtValue();
8929 if (TrueSDVals.empty() || FalseSDVals.empty())
8932 for (
auto &CCVal : {0, 1, 2, 3})
8933 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8935 : FalseSDVals[CCVal]);
8936 return MergedSDVals;
8953 if (Op0SDVals.empty() || Op1SDVals.empty())
8956 for (
auto CCVal : {0, 1, 2, 3})
8958 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8959 return BinaryOpSDVals;
8970 auto *CCNode = CCReg.
getNode();
8974 if (CCNode->getOpcode() == SystemZISD::TM) {
8977 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8980 if (!Op0Node || !Op1Node)
8982 auto Op0APVal = Op0Node->getAPIntValue();
8983 auto Op1APVal = Op1Node->getAPIntValue();
8984 auto Result = Op0APVal & Op1APVal;
8985 bool AllOnes = Result == Op1APVal;
8986 bool AllZeros = Result == 0;
8987 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8988 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8992 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8997 if (Op0SDVals.empty() || Op1SDVals.empty())
9000 for (
auto CC : {0, 1, 2, 3}) {
9001 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
9005 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
9007 NewCCMask &= Op0CCValid;
9010 CCValid = Op0CCValid;
9013 if (CCNode->getOpcode() != SystemZISD::ICMP ||
9020 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
9024 if (Op0SDVals.empty() || Op1SDVals.empty())
9028 auto CmpTypeVal = CmpType->getZExtValue();
9029 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
9033 if (!Op0Node || !Op1Node)
9035 auto Op0APVal = Op0Node->getAPIntValue();
9036 auto Op1APVal = Op1Node->getAPIntValue();
9038 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
9039 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
9042 for (
auto CC : {0, 1, 2, 3}) {
9043 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
9047 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
9049 NewCCMask &= Op0CCValid;
9052 CCValid = Op0CCValid;
9065 const auto isFlagOutOpCC = [](
const Value *V) {
9067 const Value *RHSVal;
9074 if (CB->isInlineAsm()) {
9076 return IA && IA->getConstraintString().contains(
"{@cc}");
9087 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
9090 return {-1, -1, -1};
9094 DAGCombinerInfo &DCI)
const {
9100 if (!CCValid || !CCMask)
9103 int CCValidVal = CCValid->getZExtValue();
9104 int CCMaskVal = CCMask->getZExtValue();
9111 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9112 CCMaskVal != CCValidVal)
9113 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9117 N->getOperand(3), CCReg);
9121SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9122 SDNode *
N, DAGCombinerInfo &DCI)
const {
9128 if (!CCValid || !CCMask)
9131 int CCValidVal = CCValid->getZExtValue();
9132 int CCMaskVal = CCMask->getZExtValue();
9135 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9139 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9140 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9142 if (Val.getOperand(4) != CCReg)
9149 int CCMaskVal = CCMask->getZExtValue();
9150 for (
auto &CC : {0, 1, 2, 3})
9151 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9159 SDValue
TrueVal =
N->getOperand(0);
9165 if (TrueSDVals.empty())
9166 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9167 if (FalseSDVals.empty())
9168 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9169 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9170 SmallSet<SDValue, 4> MergedSDValsSet;
9172 for (
auto CC : {0, 1, 2, 3}) {
9173 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9174 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9178 if (MergedSDValsSet.
size() == 1)
9179 return *MergedSDValsSet.
begin();
9180 if (MergedSDValsSet.
size() == 2) {
9181 auto BeginIt = MergedSDValsSet.
begin();
9182 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9183 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9186 for (
auto CC : {0, 1, 2, 3}) {
9188 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9189 ? (TrueSDVals[CC] == NewTrueVal)
9190 : (FalseSDVals[CC] == NewTrueVal);
9192 CCMaskVal = NewCCMask;
9193 CCMaskVal &= CCValidVal;
9196 IsCombinedCCReg =
true;
9204 if (CCMaskVal == CCValidVal)
9207 if (IsCombinedCCReg)
9209 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9216SDValue SystemZTargetLowering::combineGET_CCMASK(
9217 SDNode *
N, DAGCombinerInfo &DCI)
const {
9222 if (!CCValid || !CCMask)
9224 int CCValidVal = CCValid->getZExtValue();
9225 int CCMaskVal = CCMask->getZExtValue();
9227 SDValue
Select =
N->getOperand(0);
9230 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9235 if (!SelectCCValid || !SelectCCMask)
9237 int SelectCCValidVal = SelectCCValid->getZExtValue();
9238 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9242 if (!TrueVal || !FalseVal)
9246 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9247 SelectCCMaskVal ^= SelectCCValidVal;
9251 if (SelectCCValidVal & ~CCValidVal)
9253 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9256 return Select->getOperand(4);
9259SDValue SystemZTargetLowering::combineIntDIVREM(
9260 SDNode *
N, DAGCombinerInfo &DCI)
const {
9261 SelectionDAG &DAG = DCI.DAG;
9262 EVT VT =
N->getValueType(0);
9279SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9280 SDNode *
N, DAGCombinerInfo &DCI)
const {
9281 SelectionDAG &DAG = DCI.DAG;
9285 "SRL or SRA node is required here!");
9287 if (!Subtarget.hasVector())
9297 SDValue ShiftOperand =
N->getOperand(0);
9317 if (!IsSignExt && !IsZeroExt)
9323 SDValue MulhRightOp;
9325 unsigned ActiveBits = IsSignExt
9326 ?
Constant->getAPIntValue().getSignificantBits()
9327 :
Constant->getAPIntValue().getActiveBits();
9328 if (ActiveBits > NarrowVTSize)
9344 unsigned ActiveBits = IsSignExt
9345 ?
Constant->getAPIntValue().getSignificantBits()
9346 :
Constant->getAPIntValue().getActiveBits();
9347 if (ActiveBits > NarrowVTSize)
9364 "Cannot have a multiply node with two different operand types.");
9366 "Cannot have an add node with two different operand types.");
9377 if (ShiftAmt != NarrowVTSize)
9381 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9382 NarrowVT == MVT::v4i32 ||
9383 (Subtarget.hasVectorEnhancements3() &&
9384 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9388 SDValue
Result = DAG.
getNode(IsSignExt ? SystemZISD::VMAH : SystemZISD::VMALH,
9390 MulhRightOp, MulhAddOp);
9391 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9402 EVT VT =
Op.getValueType();
9411 Op =
Op.getOperand(0);
9412 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9416 bool CanUseEven =
true, CanUseOdd =
true;
9417 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9418 if (ShuffleMask[Elt] == -1)
9420 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9422 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9425 Op =
Op.getOperand(0);
9427 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9429 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9435 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9439 Op =
Op.getOperand(0);
9441 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9443 unsigned Elem =
Op.getConstantOperandVal(1);
9444 Op =
Op.getOperand(0);
9446 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9448 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9455SDValue SystemZTargetLowering::combineMUL(
9456 SDNode *
N, DAGCombinerInfo &DCI)
const {
9457 SelectionDAG &DAG = DCI.DAG;
9464 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9465 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9470SDValue SystemZTargetLowering::combineINTRINSIC(
9471 SDNode *
N, DAGCombinerInfo &DCI)
const {
9472 SelectionDAG &DAG = DCI.DAG;
9474 unsigned Id =
N->getConstantOperandVal(1);
9478 case Intrinsic::s390_vll:
9479 case Intrinsic::s390_vlrl:
9481 if (
C->getZExtValue() >= 15)
9482 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9483 N->getOperand(3), MachinePointerInfo());
9486 case Intrinsic::s390_vstl:
9487 case Intrinsic::s390_vstrl:
9489 if (
C->getZExtValue() >= 15)
9490 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9491 N->getOperand(4), MachinePointerInfo());
9499 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9506 switch(
N->getOpcode()) {
9511 case SystemZISD::MERGE_HIGH:
9512 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9517 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9527 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9528 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9531 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9532 case ISD::MUL:
return combineMUL(
N, DCI);
9536 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9548 EVT VT =
Op.getValueType();
9551 unsigned Opcode =
Op.getOpcode();
9553 unsigned Id =
Op.getConstantOperandVal(0);
9555 case Intrinsic::s390_vpksh:
9556 case Intrinsic::s390_vpksf:
9557 case Intrinsic::s390_vpksg:
9558 case Intrinsic::s390_vpkshs:
9559 case Intrinsic::s390_vpksfs:
9560 case Intrinsic::s390_vpksgs:
9561 case Intrinsic::s390_vpklsh:
9562 case Intrinsic::s390_vpklsf:
9563 case Intrinsic::s390_vpklsg:
9564 case Intrinsic::s390_vpklshs:
9565 case Intrinsic::s390_vpklsfs:
9566 case Intrinsic::s390_vpklsgs:
9568 SrcDemE = DemandedElts;
9571 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9574 case Intrinsic::s390_vuphb:
9575 case Intrinsic::s390_vuphh:
9576 case Intrinsic::s390_vuphf:
9577 case Intrinsic::s390_vuplhb:
9578 case Intrinsic::s390_vuplhh:
9579 case Intrinsic::s390_vuplhf:
9580 SrcDemE =
APInt(NumElts * 2, 0);
9583 case Intrinsic::s390_vuplb:
9584 case Intrinsic::s390_vuplhw:
9585 case Intrinsic::s390_vuplf:
9586 case Intrinsic::s390_vupllb:
9587 case Intrinsic::s390_vupllh:
9588 case Intrinsic::s390_vupllf:
9589 SrcDemE =
APInt(NumElts * 2, 0);
9592 case Intrinsic::s390_vpdi: {
9594 SrcDemE =
APInt(NumElts, 0);
9595 if (!DemandedElts[OpNo - 1])
9597 unsigned Mask =
Op.getConstantOperandVal(3);
9598 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9600 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9603 case Intrinsic::s390_vsldb: {
9605 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9606 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9607 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9608 unsigned NumSrc0Els = 16 - FirstIdx;
9609 SrcDemE =
APInt(NumElts, 0);
9611 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9614 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9619 case Intrinsic::s390_vperm:
9628 case SystemZISD::JOIN_DWORDS:
9630 SrcDemE =
APInt(1, 1);
9632 case SystemZISD::SELECT_CCMASK:
9633 SrcDemE = DemandedElts;
9644 const APInt &DemandedElts,
9659 const APInt &DemandedElts,
9661 unsigned Depth)
const {
9665 unsigned Tmp0, Tmp1;
9667 Known.Zero.setBitsFrom(2);
9670 [[maybe_unused]]
EVT VT =
Op.getValueType();
9671 if (
Op.getResNo() != 0)
9674 "KnownBits does not match VT in bitwidth");
9677 "DemandedElts does not match VT number of elements");
9679 unsigned Opcode =
Op.getOpcode();
9681 bool IsLogical =
false;
9682 unsigned Id =
Op.getConstantOperandVal(0);
9684 case Intrinsic::s390_vpksh:
9685 case Intrinsic::s390_vpksf:
9686 case Intrinsic::s390_vpksg:
9687 case Intrinsic::s390_vpkshs:
9688 case Intrinsic::s390_vpksfs:
9689 case Intrinsic::s390_vpksgs:
9690 case Intrinsic::s390_vpklsh:
9691 case Intrinsic::s390_vpklsf:
9692 case Intrinsic::s390_vpklsg:
9693 case Intrinsic::s390_vpklshs:
9694 case Intrinsic::s390_vpklsfs:
9695 case Intrinsic::s390_vpklsgs:
9696 case Intrinsic::s390_vpdi:
9697 case Intrinsic::s390_vsldb:
9698 case Intrinsic::s390_vperm:
9701 case Intrinsic::s390_vuplhb:
9702 case Intrinsic::s390_vuplhh:
9703 case Intrinsic::s390_vuplhf:
9704 case Intrinsic::s390_vupllb:
9705 case Intrinsic::s390_vupllh:
9706 case Intrinsic::s390_vupllf:
9709 case Intrinsic::s390_vuphb:
9710 case Intrinsic::s390_vuphh:
9711 case Intrinsic::s390_vuphf:
9712 case Intrinsic::s390_vuplb:
9713 case Intrinsic::s390_vuplhw:
9714 case Intrinsic::s390_vuplf: {
9729 case SystemZISD::JOIN_DWORDS:
9730 case SystemZISD::SELECT_CCMASK:
9733 case SystemZISD::REPLICATE: {
9756 if (
LHS == 1)
return 1;
9759 if (
RHS == 1)
return 1;
9760 unsigned Common = std::min(
LHS,
RHS);
9761 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9762 EVT VT =
Op.getValueType();
9764 if (SrcBitWidth > VTBits) {
9765 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9766 if (Common > SrcExtraBits)
9767 return (Common - SrcExtraBits);
9770 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9777 unsigned Depth)
const {
9778 if (
Op.getResNo() != 0)
9780 unsigned Opcode =
Op.getOpcode();
9782 unsigned Id =
Op.getConstantOperandVal(0);
9784 case Intrinsic::s390_vpksh:
9785 case Intrinsic::s390_vpksf:
9786 case Intrinsic::s390_vpksg:
9787 case Intrinsic::s390_vpkshs:
9788 case Intrinsic::s390_vpksfs:
9789 case Intrinsic::s390_vpksgs:
9790 case Intrinsic::s390_vpklsh:
9791 case Intrinsic::s390_vpklsf:
9792 case Intrinsic::s390_vpklsg:
9793 case Intrinsic::s390_vpklshs:
9794 case Intrinsic::s390_vpklsfs:
9795 case Intrinsic::s390_vpklsgs:
9796 case Intrinsic::s390_vpdi:
9797 case Intrinsic::s390_vsldb:
9798 case Intrinsic::s390_vperm:
9800 case Intrinsic::s390_vuphb:
9801 case Intrinsic::s390_vuphh:
9802 case Intrinsic::s390_vuphf:
9803 case Intrinsic::s390_vuplb:
9804 case Intrinsic::s390_vuplhw:
9805 case Intrinsic::s390_vuplf: {
9809 EVT VT =
Op.getValueType();
9819 case SystemZISD::SELECT_CCMASK:
9832 switch (
Op->getOpcode()) {
9833 case SystemZISD::PCREL_WRAPPER:
9834 case SystemZISD::PCREL_OFFSET:
9845 "Unexpected stack alignment");
9848 unsigned StackProbeSize =
9851 StackProbeSize &= ~(StackAlign - 1);
9852 return StackProbeSize ? StackProbeSize : StackAlign;
9891 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9893 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9899 if (miI ==
MBB->end()) {
9901 if (Succ->isLiveIn(SystemZ::CC))
9912 switch (
MI.getOpcode()) {
9913 case SystemZ::Select32:
9914 case SystemZ::Select64:
9915 case SystemZ::Select128:
9916 case SystemZ::SelectF32:
9917 case SystemZ::SelectF64:
9918 case SystemZ::SelectF128:
9919 case SystemZ::SelectVR32:
9920 case SystemZ::SelectVR64:
9921 case SystemZ::SelectVR128:
9953 for (
auto *
MI : Selects) {
9954 Register DestReg =
MI->getOperand(0).getReg();
9955 Register TrueReg =
MI->getOperand(1).getReg();
9956 Register FalseReg =
MI->getOperand(2).getReg();
9961 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9964 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9965 TrueReg = It->second.first;
9967 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9968 FalseReg = It->second.second;
9971 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9976 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9987 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9988 assert(TFL->hasReservedCallFrame(MF) &&
9989 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9994 uint32_t NumBytes =
MI.getOperand(0).getImm();
9999 MI.eraseFromParent();
10008 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10010 unsigned CCValid =
MI.getOperand(3).getImm();
10011 unsigned CCMask =
MI.getOperand(4).getImm();
10016 SmallVector<MachineInstr*, 8> Selects;
10017 SmallVector<MachineInstr*, 8> DbgValues;
10019 unsigned Count = 0;
10023 assert(NextMI.getOperand(3).getImm() == CCValid &&
10024 "Bad CCValid operands since CC was not redefined.");
10025 if (NextMI.getOperand(4).getImm() == CCMask ||
10026 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
10032 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
10033 NextMI.usesCustomInsertionHook())
10036 for (
auto *SelMI : Selects)
10037 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
10041 if (NextMI.isDebugInstr()) {
10043 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
10046 }
else if (User || ++
Count > 20)
10050 MachineInstr *LastMI = Selects.back();
10051 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
10053 MachineBasicBlock *StartMBB =
MBB;
10083 for (
auto *SelMI : Selects)
10084 SelMI->eraseFromParent();
10087 for (
auto *DbgMI : DbgValues)
10088 MBB->
splice(InsertPos, StartMBB, DbgMI);
10099 unsigned StoreOpcode,
10100 unsigned STOCOpcode,
10101 bool Invert)
const {
10102 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10104 Register SrcReg =
MI.getOperand(0).getReg();
10105 MachineOperand
Base =
MI.getOperand(1);
10106 int64_t Disp =
MI.getOperand(2).getImm();
10107 Register IndexReg =
MI.getOperand(3).getReg();
10108 unsigned CCValid =
MI.getOperand(4).getImm();
10109 unsigned CCMask =
MI.getOperand(5).getImm();
10112 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10116 MachineMemOperand *MMO =
nullptr;
10117 for (
auto *
I :
MI.memoperands())
10118 if (
I->isStore()) {
10126 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10138 MI.eraseFromParent();
10146 MachineBasicBlock *StartMBB =
MBB;
10152 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10179 MI.eraseFromParent();
10189 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10197 MachineBasicBlock *StartMBB =
MBB;
10215 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10242 MI.eraseFromParent();
10253 bool Invert)
const {
10255 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10262 int64_t Disp =
MI.getOperand(2).getImm();
10264 Register BitShift =
MI.getOperand(4).getReg();
10265 Register NegBitShift =
MI.getOperand(5).getReg();
10266 unsigned BitSize =
MI.getOperand(6).getImm();
10270 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10271 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10272 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10282 MachineBasicBlock *StartMBB =
MBB;
10318 .
addImm(-1U << (32 - BitSize))
10320 }
else if (BinOpcode)
10348 MI.eraseFromParent();
10359 unsigned KeepOldMask)
const {
10361 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10367 int64_t Disp =
MI.getOperand(2).getImm();
10369 Register BitShift =
MI.getOperand(4).getReg();
10370 Register NegBitShift =
MI.getOperand(5).getReg();
10371 unsigned BitSize =
MI.getOperand(6).getImm();
10375 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10376 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10377 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10388 MachineBasicBlock *StartMBB =
MBB;
10456 MI.eraseFromParent();
10466 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10472 int64_t Disp =
MI.getOperand(2).getImm();
10473 Register CmpVal =
MI.getOperand(3).getReg();
10474 Register OrigSwapVal =
MI.getOperand(4).getReg();
10475 Register BitShift =
MI.getOperand(5).getReg();
10476 Register NegBitShift =
MI.getOperand(6).getReg();
10477 int64_t BitSize =
MI.getOperand(7).getImm();
10483 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10484 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10485 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10486 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10498 MachineBasicBlock *StartMBB =
MBB;
10575 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10578 MI.eraseFromParent();
10585 unsigned Opcode,
bool IsMemset)
const {
10587 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10592 uint64_t DestDisp =
MI.getOperand(1).getImm();
10597 auto foldDisplIfNeeded = [&](MachineOperand &
Base,
uint64_t &Disp) ->
void {
10600 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10610 SrcDisp =
MI.getOperand(3).getImm();
10612 SrcBase = DestBase;
10613 SrcDisp = DestDisp++;
10614 foldDisplIfNeeded(DestBase, DestDisp);
10617 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10618 bool IsImmForm = LengthMO.
isImm();
10619 bool IsRegForm = !IsImmForm;
10622 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10624 MachineOperand DBase,
uint64_t DDisp,
10626 unsigned Length) ->
void {
10630 if (ByteMO.
isImm())
10645 bool NeedsLoop =
false;
10647 Register LenAdjReg = SystemZ::NoRegister;
10649 ImmLength = LengthMO.
getImm();
10650 ImmLength += IsMemset ? 2 : 1;
10651 if (ImmLength == 0) {
10652 MI.eraseFromParent();
10655 if (Opcode == SystemZ::CLC) {
10656 if (ImmLength > 3 * 256)
10666 }
else if (ImmLength > 6 * 256)
10674 LenAdjReg = LengthMO.
getReg();
10679 MachineBasicBlock *EndMBB =
10680 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10688 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10698 auto loadZeroAddress = [&]() -> MachineOperand {
10703 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10704 DestBase = loadZeroAddress();
10705 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10706 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10708 MachineBasicBlock *StartMBB =
nullptr;
10709 MachineBasicBlock *LoopMBB =
nullptr;
10710 MachineBasicBlock *NextMBB =
nullptr;
10711 MachineBasicBlock *DoneMBB =
nullptr;
10712 MachineBasicBlock *AllDoneMBB =
nullptr;
10716 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10725 RC = &SystemZ::GR64BitRegClass;
10753 MBB = MemsetOneCheckMBB;
10764 MBB = MemsetOneMBB;
10796 if (EndMBB && !ImmLength)
10818 if (!HaveSingleBase)
10825 if (Opcode == SystemZ::MVC)
10852 if (!HaveSingleBase)
10877 Register RemDestReg = HaveSingleBase ? RemSrcReg
10882 if (!HaveSingleBase)
10890 MachineInstrBuilder EXRL_MIB =
10898 if (Opcode != SystemZ::MVC) {
10908 while (ImmLength > 0) {
10912 foldDisplIfNeeded(DestBase, DestDisp);
10913 foldDisplIfNeeded(SrcBase, SrcDisp);
10914 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10915 DestDisp += ThisLength;
10916 SrcDisp += ThisLength;
10917 ImmLength -= ThisLength;
10920 if (EndMBB && ImmLength > 0) {
10936 MI.eraseFromParent();
10943 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10949 assert(Len > 0 && Len <= 256 &&
"Memmove of of unsupported constant length.");
10978 MI.eraseFromParent();
10987 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10991 uint64_t End1Reg =
MI.getOperand(0).getReg();
10992 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10993 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10994 uint64_t CharReg =
MI.getOperand(3).getReg();
11001 MachineBasicBlock *StartMBB =
MBB;
11037 MI.eraseFromParent();
11044 bool NoFloat)
const {
11046 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
11047 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11050 MI.setDesc(
TII->get(Opcode));
11054 uint64_t Control =
MI.getOperand(2).getImm();
11055 static const unsigned GPRControlBit[16] = {
11056 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
11057 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
11059 Control |= GPRControlBit[15];
11060 if (TFI->
hasFP(MF))
11061 Control |= GPRControlBit[11];
11062 MI.getOperand(2).setImm(Control);
11065 for (
int I = 0;
I < 16;
I++) {
11066 if ((Control & GPRControlBit[
I]) == 0) {
11073 if (!NoFloat && (Control & 4) != 0) {
11074 if (Subtarget.hasVector()) {
11091 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11092 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11095 Register SrcReg =
MI.getOperand(0).getReg();
11106 MI.eraseFromParent();
11114 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11115 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11118 Register DstReg =
MI.getOperand(0).getReg();
11119 Register SizeReg =
MI.getOperand(2).getReg();
11121 MachineBasicBlock *StartMBB =
MBB;
11208 MI.eraseFromParent();
11212SDValue SystemZTargetLowering::
11215 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11227 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11232 .
addImm(
MI.getOperand(1).getImm());
11233 MI.eraseFromParent();
11239 switch (
MI.getOpcode()) {
11240 case SystemZ::ADJCALLSTACKDOWN:
11241 case SystemZ::ADJCALLSTACKUP:
11242 return emitAdjCallStack(
MI,
MBB);
11244 case SystemZ::Select32:
11245 case SystemZ::Select64:
11246 case SystemZ::Select128:
11247 case SystemZ::SelectF32:
11248 case SystemZ::SelectF64:
11249 case SystemZ::SelectF128:
11250 case SystemZ::SelectVR32:
11251 case SystemZ::SelectVR64:
11252 case SystemZ::SelectVR128:
11253 return emitSelect(
MI,
MBB);
11255 case SystemZ::CondStore8Mux:
11256 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11257 case SystemZ::CondStore8MuxInv:
11258 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11259 case SystemZ::CondStore16Mux:
11260 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11261 case SystemZ::CondStore16MuxInv:
11262 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11263 case SystemZ::CondStore32Mux:
11264 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11265 case SystemZ::CondStore32MuxInv:
11266 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11267 case SystemZ::CondStore8:
11268 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11269 case SystemZ::CondStore8Inv:
11270 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11271 case SystemZ::CondStore16:
11272 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11273 case SystemZ::CondStore16Inv:
11274 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11275 case SystemZ::CondStore32:
11276 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11277 case SystemZ::CondStore32Inv:
11278 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11279 case SystemZ::CondStore64:
11280 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11281 case SystemZ::CondStore64Inv:
11282 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11283 case SystemZ::CondStoreF32:
11284 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11285 case SystemZ::CondStoreF32Inv:
11286 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11287 case SystemZ::CondStoreF64:
11288 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11289 case SystemZ::CondStoreF64Inv:
11290 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11292 case SystemZ::SCmp128Hi:
11293 return emitICmp128Hi(
MI,
MBB,
false);
11294 case SystemZ::UCmp128Hi:
11295 return emitICmp128Hi(
MI,
MBB,
true);
11298 case SystemZ::ATOMIC_SWAPW:
11299 return emitAtomicLoadBinary(
MI,
MBB, 0);
11301 case SystemZ::ATOMIC_LOADW_AR:
11302 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11303 case SystemZ::ATOMIC_LOADW_AFI:
11304 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11306 case SystemZ::ATOMIC_LOADW_SR:
11307 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11309 case SystemZ::ATOMIC_LOADW_NR:
11310 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11311 case SystemZ::ATOMIC_LOADW_NILH:
11312 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11314 case SystemZ::ATOMIC_LOADW_OR:
11315 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11316 case SystemZ::ATOMIC_LOADW_OILH:
11317 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11319 case SystemZ::ATOMIC_LOADW_XR:
11320 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11321 case SystemZ::ATOMIC_LOADW_XILF:
11322 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11324 case SystemZ::ATOMIC_LOADW_NRi:
11325 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11326 case SystemZ::ATOMIC_LOADW_NILHi:
11327 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11329 case SystemZ::ATOMIC_LOADW_MIN:
11331 case SystemZ::ATOMIC_LOADW_MAX:
11333 case SystemZ::ATOMIC_LOADW_UMIN:
11335 case SystemZ::ATOMIC_LOADW_UMAX:
11338 case SystemZ::ATOMIC_CMP_SWAPW:
11339 return emitAtomicCmpSwapW(
MI,
MBB);
11340 case SystemZ::MVCImm:
11341 case SystemZ::MVCReg:
11342 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11343 case SystemZ::NCImm:
11344 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11345 case SystemZ::OCImm:
11346 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11347 case SystemZ::XCImm:
11348 case SystemZ::XCReg:
11349 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11350 case SystemZ::CLCImm:
11351 case SystemZ::CLCReg:
11352 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11353 case SystemZ::MemsetImmImm:
11354 case SystemZ::MemsetImmReg:
11355 case SystemZ::MemsetRegImm:
11356 case SystemZ::MemsetRegReg:
11357 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11358 case SystemZ::MemmoveImm:
11359 return emitMemmoveImm(
MI,
MBB);
11360 case SystemZ::CLSTLoop:
11361 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11362 case SystemZ::MVSTLoop:
11363 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11364 case SystemZ::SRSTLoop:
11365 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11366 case SystemZ::TBEGIN:
11367 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11368 case SystemZ::TBEGIN_nofloat:
11369 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11370 case SystemZ::TBEGINC:
11371 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11372 case SystemZ::LTEBRCompare_Pseudo:
11373 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11374 case SystemZ::LTDBRCompare_Pseudo:
11375 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11376 case SystemZ::LTXBRCompare_Pseudo:
11377 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11379 case SystemZ::PROBED_ALLOCA:
11380 return emitProbedAlloca(
MI,
MBB);
11381 case SystemZ::EH_SjLj_SetJmp:
11383 case SystemZ::EH_SjLj_LongJmp:
11386 case TargetOpcode::STACKMAP:
11387 case TargetOpcode::PATCHPOINT:
11390 case SystemZ::MOV_STACKGUARD_DAG:
11391 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11393 case SystemZ::CMP_STACKGUARD_DAG:
11394 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11423 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11443 EVT VT =
Op.getValueType();
11444 Op =
Op.getOperand(0);
11445 EVT OpVT =
Op.getValueType();
11447 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11458 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11479 if (Attrs.hasRetAttrs())
11480 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11481 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11482 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11485 OS << *FT->getParamType(
I);
11487 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11496bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11497 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11498 if (Itr == IsInternalCache.end())
11499 Itr = IsInternalCache
11500 .insert(std::pair<const Function *, bool>(
11503 return Itr->second;
11506bool SystemZTargetLowering::enableNarrowIntArgsVerification()
const {
11507 if (!Subtarget.isTargetELF())
11520void SystemZTargetLowering::verifyNarrowIntegerArgs_Call(
11523 if (!enableNarrowIntArgsVerification())
11525 bool IsInternal =
false;
11526 const Function *CalleeFn =
nullptr;
11529 IsInternal = isInternal(CalleeFn);
11531 if (!verifyNarrowIntegerArgs(C_ABI, Outs, CalleeFn,
false)) {
11532 errs() <<
"Callee: ";
11533 if (CalleeFn !=
nullptr)
11537 errs() <<
"Caller: ";
11540 errs() <<
" " << *CLI.CB;
11543 LLVM_DEBUG(
dbgs() <<
"Outgoing call arguments verified as ABI compliant: ";
11545 else dbgs() <<
"-\n";);
11548void SystemZTargetLowering::verifyNarrowIntegerArgs_Ret(
11551 if (!enableNarrowIntArgsVerification())
11554 if (!verifyNarrowIntegerArgs(C_ABI, Outs,
F,
true)) {
11555 errs() <<
"Returning from function: ";
11559 LLVM_DEBUG(
dbgs() <<
"Return argument verified as ABI compliant : ";
11566bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11568 const Function *FunHeader,
bool IsRet)
const {
11569 if (IsRet && Outs.
size() != 1)
11572 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11573 EVT OrigArgVT = Outs[i].ArgVT;
11576 assert(Outs[i].VT == MVT::i32 &&
"Unexpected integer argument VT.");
11577 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11578 unsigned OrigIdx = Outs[i].OrigArgIndex;
11581 if (C_ABI && !
Flags.isSExt() && !
Flags.isZExt() && !
Flags.isNoExt()) {
11582 errs() <<
"ERROR: (C ABI violation) missing extension attribute on "
11583 << (IsRet ?
"return value" : Twine(
"arg ") + Twine(OrigIdx))
11590 const AttributeList &FunAttrs = FunHeader->
getAttributes();
11591 const AttributeSet
Attrs =
11592 IsRet ? FunAttrs.getRetAttrs() : FunAttrs.getParamAttrs(OrigIdx);
11593 if (
Attrs.hasAttribute(Attribute::SExt) && !
Flags.isSExt()) {
11594 errs() <<
"ERROR: Missing SExt on arg " << OrigIdx <<
".\n";
11597 if (
Attrs.hasAttribute(Attribute::ZExt) && !
Flags.isZExt()) {
11598 errs() <<
"ERROR: Missing ZExt on arg " << OrigIdx <<
".\n";
11609 StringRef GuardMode = M.getStackProtectorGuard();
11612 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 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 bool isInBoundsConstantVectorIndex(EVT VecVT, SDValue Idx)
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 void printFunctionArgExts(const Function *F, raw_ostream &OS)
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...
AttributeList getAttributes() const
Return the attribute list for this Function.
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.
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...
bool canMergeStoresTo(unsigned AS, EVT MemVT, const MachineFunction &MF) const override
Returns if it's reasonable to merge stores to MemVT size.
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.
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns how the legalizer should materialize the specified FP immediate.
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...
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...
bool aggressivelyPreferBuildVectorSources(EVT VecVT) const override
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.
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
@ Legal
The target can instruction select the immediate natively.
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.
unsigned VerifyArgABICompliance
When set to true, call/return argument extensions of narrow integers are verified in the target backe...
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
This class implements an extremely fast bulk output stream that can only output to a stream.
#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 char Attrs[]
Key for Kernel::Metadata::mAttrs.
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 - Same semantics as the llvm.minnum/maxnum intrinsics.
@ 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 - Same semantics as the llvm.minimum/maximum intrinsics.
@ 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 - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ 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.