27#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()) {
130 if (Subtarget.hasVector())
157 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
158 I <= MVT::LAST_FP_VALUETYPE;
184 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
185 I <= MVT::LAST_INTEGER_VALUETYPE;
216 if (Subtarget.hasPopulationCount())
242 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
263 if (!Subtarget.hasVectorEnhancements3()) {
290 if (Subtarget.hasVectorEnhancements3()) {
333 {MVT::i8, MVT::i16, MVT::i32},
Legal);
335 {MVT::i8, MVT::i16},
Legal);
356 if (Subtarget.hasMiscellaneousExtensions4()) {
363 if (Subtarget.hasMiscellaneousExtensions3()) {
456 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
461 if (Subtarget.hasVectorEnhancements3() &&
462 VT != MVT::v16i8 && VT != MVT::v8i16) {
472 if (Subtarget.hasVectorEnhancements1())
506 if (Subtarget.hasVector()) {
528 if (Subtarget.hasVectorEnhancements2()) {
554 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
568 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
569 I <= MVT::LAST_FP_VALUETYPE;
577 if (Subtarget.hasFPExtension()) {
605 if (Subtarget.hasFPExtension()) {
621 if (Subtarget.hasVector()) {
669 if (Subtarget.hasVectorEnhancements1()) {
676 if (Subtarget.hasVectorEnhancements1()) {
732 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
733 MVT::v4f32, MVT::v2f64 }) {
742 if (!Subtarget.hasVectorEnhancements1()) {
748 if (Subtarget.hasVectorEnhancements1())
758 if (Subtarget.hasVectorEnhancements1()) {
770 if (!Subtarget.hasVector()) {
781 if (Subtarget.isTargetzOS()) {
842 return Subtarget.hasSoftFloat();
867 return Subtarget.hasVectorEnhancements1();
880 if (!Subtarget.hasVector() ||
881 (isFP128 && !Subtarget.hasVectorEnhancements1()))
890 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
897 Opcode = SystemZISD::BYTE_MASK;
903 if (SplatBitSize > 64)
910 OpVals.push_back(((
unsigned) SignedValue));
911 Opcode = SystemZISD::REPLICATE;
918 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start, End)) {
922 OpVals.push_back(Start - (64 - SplatBitSize));
923 OpVals.push_back(End - (64 - SplatBitSize));
924 Opcode = SystemZISD::ROTATE_MASK;
936 uint64_t SplatBitsZ = SplatBits.getZExtValue();
937 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
949 return TryValue(SplatBitsZ | Middle);
958 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
964 unsigned HalfSize = Width / 2;
969 if (HighValue != LowValue || 8 > HalfSize)
972 SplatBits = HighValue;
976 SplatBitSize = Width;
984 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
988 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
993 bool ForCodeSize)
const {
995 if (Imm.isZero() || Imm.isNegZero())
1016 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1018 Register MainDstReg =
MRI.createVirtualRegister(RC);
1019 Register RestoreDstReg =
MRI.createVirtualRegister(RC);
1022 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1075 const int64_t FPOffset = 0;
1084 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
1096 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1097 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1100 .
addReg(SpecialRegs->getFramePointerRegister())
1108 .
addReg(SpecialRegs->getStackPointerRegister())
1116 Register BCReg =
MRI.createVirtualRegister(PtrRC);
1119 .
addReg(SpecialRegs->getStackPointerRegister())
1120 .
addImm(TFL->getBackchainOffset(*MF))
1131 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1135 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1156 MI.eraseFromParent();
1172 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1175 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1182 const int64_t FPOffset = 0;
1194 SpecialRegs->getFramePointerRegister())
1216 SpecialRegs->getStackPointerRegister())
1225 .
addReg(SpecialRegs->getStackPointerRegister())
1226 .
addImm(TFL->getBackchainOffset(*MF))
1232 MI.eraseFromParent();
1263 if (Subtarget.hasInterlockedAccess1() &&
1296 EVT VT =
Y.getValueType();
1299 if (VT == MVT::i32 || VT == MVT::i64)
1300 return Subtarget.hasMiscellaneousExtensions3();
1303 if (VT.
isVector() || VT == MVT::i128)
1304 return Subtarget.hasVector();
1332 bool MVC = Ty->isIntegerTy(8);
1338static AddressingMode
1341 switch (
II->getIntrinsicID()) {
1343 case Intrinsic::memset:
1344 case Intrinsic::memmove:
1345 case Intrinsic::memcpy:
1352 if (SingleUser->getParent() ==
I->getParent()) {
1355 if (
C->getBitWidth() <= 64 &&
1365 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1379 I->getOperand(0)->getType());
1381 bool IsVectorAccess = MemAccessTy->isVectorTy();
1386 Value *DataOp =
I->getOperand(0);
1388 IsVectorAccess =
true;
1394 User *LoadUser = *
I->user_begin();
1396 IsVectorAccess =
true;
1399 if (IsFPAccess || IsVectorAccess)
1418 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1428 return AM.
Scale == 0;
1435 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1436 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1437 const AttributeList &FuncAttributes)
const {
1438 const int MVCFastLen = 16;
1440 if (Limit != ~
unsigned(0)) {
1442 if (
Op.isMemcpy() &&
Op.allowOverlap() &&
Op.size() <= MVCFastLen)
1444 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1446 if (
Op.isZeroMemset())
1451 DstAS, SrcAS, FuncAttributes);
1456 const AttributeList &FuncAttributes)
const {
1457 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1461 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1463 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1465 return FromBits > ToBits;
1473 return FromBits > ToBits;
1482 if (Constraint.
size() == 1) {
1483 switch (Constraint[0]) {
1509 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1510 switch (Constraint[1]) {
1521 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1531 Value *CallOperandVal = Info.CallOperandVal;
1534 if (!CallOperandVal)
1538 switch (*Constraint) {
1557 if (Subtarget.hasVector())
1588 if (
C->getZExtValue() == 0x7fffffff)
1598static std::pair<unsigned, const TargetRegisterClass *>
1600 const unsigned *Map,
unsigned Size) {
1601 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1602 if (isdigit(Constraint[2])) {
1607 return std::make_pair(Map[Index], RC);
1609 return std::make_pair(0U,
nullptr);
1612std::pair<unsigned, const TargetRegisterClass *>
1615 if (Constraint.
size() == 1) {
1617 switch (Constraint[0]) {
1622 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1624 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1625 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1629 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1630 else if (VT == MVT::i128)
1631 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1632 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1635 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1640 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1642 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1644 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1645 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1650 if (Subtarget.hasVector()) {
1652 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1654 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1656 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1657 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1666 auto getVTSizeInBits = [&VT]() {
1674 if (Constraint[1] ==
'r') {
1675 if (getVTSizeInBits() == 32)
1678 if (getVTSizeInBits() == 128)
1684 if (Constraint[1] ==
'f') {
1686 return std::make_pair(
1688 if (getVTSizeInBits() == 16)
1691 if (getVTSizeInBits() == 32)
1694 if (getVTSizeInBits() == 128)
1700 if (Constraint[1] ==
'v') {
1701 if (!Subtarget.hasVector())
1702 return std::make_pair(
1704 if (getVTSizeInBits() == 16)
1707 if (getVTSizeInBits() == 32)
1710 if (getVTSizeInBits() == 64)
1716 if (Constraint[1] ==
'@') {
1717 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1718 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1731 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1732 : SystemZ::NoRegister)
1734 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1741 const Constant *PersonalityFn)
const {
1742 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1746 const Constant *PersonalityFn)
const {
1747 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1762 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1766 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1767 OpInfo.ConstraintVT.getSizeInBits() < 8)
1782 if (Constraint.
size() == 1) {
1783 switch (Constraint[0]) {
1788 Op.getValueType()));
1795 Op.getValueType()));
1802 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1809 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1814 if (
C->getZExtValue() == 0x7fffffff)
1816 Op.getValueType()));
1827#include "SystemZGenCallingConv.inc"
1831 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1837 Type *ToType)
const {
1900 if (BitCastToType == MVT::v2i64)
1927 MVT::Untyped,
Hi,
Lo);
1951 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1953 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1964 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
1965 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1976template <
class ArgTy>
1979 MVT &PartVT,
unsigned &NumParts) {
1980 if (!Args[
I].Flags.isSplit())
1984 PartVT = ArgLocs[
I].getValVT();
1986 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
1987 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
1988 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
1990 if (Args[PartIdx].Flags.isSplitEnd())
2014 unsigned NumFixedGPRs = 0;
2015 unsigned NumFixedFPRs = 0;
2016 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2029 RC = &SystemZ::GR32BitRegClass;
2033 RC = &SystemZ::GR64BitRegClass;
2037 RC = &SystemZ::FP16BitRegClass;
2041 RC = &SystemZ::FP32BitRegClass;
2045 RC = &SystemZ::FP64BitRegClass;
2049 RC = &SystemZ::FP128BitRegClass;
2057 RC = &SystemZ::VR128BitRegClass;
2071 if (Subtarget.isTargetXPLINK64()) {
2074 ArgSPOffset += XPRegs.getCallFrameSize();
2085 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2089 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2103 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2106 unsigned PartOffset = Ins[
I].PartOffset;
2111 assert(PartOffset &&
"Offset should be non-zero.");
2118 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2124 Subtarget.getSpecialRegisters());
2130 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2135 if (IsVarArg && Subtarget.isTargetELF()) {
2148 int64_t RegSaveOffset =
2163 &SystemZ::FP64BitRegClass);
2175 if (Subtarget.isTargetXPLINK64()) {
2180 Subtarget.getSpecialRegisters());
2181 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2193 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2200 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2202 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2209 unsigned Offset,
bool LoadAdr =
false) {
2232 bool LoadAddr =
false;
2254 unsigned ADADelta = 0;
2255 unsigned EPADelta = 8;
2261 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2262 G->getGlobal()->hasPrivateLinkage());
2269 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2315 if (Subtarget.isTargetXPLINK64())
2319 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2323 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2342 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2350 unsigned NumParts = 1;
2354 SlotVT = Outs[
I].VT;
2362 assert(Outs[
I].PartOffset == 0);
2363 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2366 unsigned PartOffset = Outs[
I].PartOffset;
2372 assert(PartOffset &&
"Offset should be non-zero.");
2374 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2376 ArgValue = SpillSlot;
2393 if (!StackPtr.getNode())
2400 else if (VA.
getLocVT() == MVT::f16)
2413 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2417 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2423 if (!MemOpChains.
empty())
2431 if (Subtarget.isTargetXPLINK64()) {
2436 ->getAddressOfCalleeRegister();
2439 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2446 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2449 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2450 }
else if (IsTailCall) {
2453 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2458 for (
const auto &[Reg,
N] : RegsToPass) {
2465 Ops.push_back(Chain);
2466 Ops.push_back(Callee);
2470 for (
const auto &[Reg,
N] : RegsToPass)
2475 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2476 assert(Mask &&
"Missing call preserved mask for calling convention");
2481 Ops.push_back(Glue);
2490 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2500 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2507 VA.getLocVT(), Glue);
2524 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2526 Args.reserve(
Ops.size());
2532 Entry.IsZExt = !Entry.IsSExt;
2533 Args.push_back(Entry);
2544 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2555 const Type *RetTy)
const {
2558 for (
auto &Out : Outs)
2559 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2563 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2564 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2576 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2584 if (RetLocs.
empty())
2585 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2594 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2616 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2623 unsigned &CCValid) {
2624 unsigned Id =
Op.getConstantOperandVal(1);
2626 case Intrinsic::s390_tbegin:
2627 Opcode = SystemZISD::TBEGIN;
2631 case Intrinsic::s390_tbegin_nofloat:
2632 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2636 case Intrinsic::s390_tend:
2637 Opcode = SystemZISD::TEND;
2650 unsigned Id =
Op.getConstantOperandVal(0);
2652 case Intrinsic::s390_vpkshs:
2653 case Intrinsic::s390_vpksfs:
2654 case Intrinsic::s390_vpksgs:
2655 Opcode = SystemZISD::PACKS_CC;
2659 case Intrinsic::s390_vpklshs:
2660 case Intrinsic::s390_vpklsfs:
2661 case Intrinsic::s390_vpklsgs:
2662 Opcode = SystemZISD::PACKLS_CC;
2666 case Intrinsic::s390_vceqbs:
2667 case Intrinsic::s390_vceqhs:
2668 case Intrinsic::s390_vceqfs:
2669 case Intrinsic::s390_vceqgs:
2670 case Intrinsic::s390_vceqqs:
2671 Opcode = SystemZISD::VICMPES;
2675 case Intrinsic::s390_vchbs:
2676 case Intrinsic::s390_vchhs:
2677 case Intrinsic::s390_vchfs:
2678 case Intrinsic::s390_vchgs:
2679 case Intrinsic::s390_vchqs:
2680 Opcode = SystemZISD::VICMPHS;
2684 case Intrinsic::s390_vchlbs:
2685 case Intrinsic::s390_vchlhs:
2686 case Intrinsic::s390_vchlfs:
2687 case Intrinsic::s390_vchlgs:
2688 case Intrinsic::s390_vchlqs:
2689 Opcode = SystemZISD::VICMPHLS;
2693 case Intrinsic::s390_vtm:
2694 Opcode = SystemZISD::VTM;
2698 case Intrinsic::s390_vfaebs:
2699 case Intrinsic::s390_vfaehs:
2700 case Intrinsic::s390_vfaefs:
2701 Opcode = SystemZISD::VFAE_CC;
2705 case Intrinsic::s390_vfaezbs:
2706 case Intrinsic::s390_vfaezhs:
2707 case Intrinsic::s390_vfaezfs:
2708 Opcode = SystemZISD::VFAEZ_CC;
2712 case Intrinsic::s390_vfeebs:
2713 case Intrinsic::s390_vfeehs:
2714 case Intrinsic::s390_vfeefs:
2715 Opcode = SystemZISD::VFEE_CC;
2719 case Intrinsic::s390_vfeezbs:
2720 case Intrinsic::s390_vfeezhs:
2721 case Intrinsic::s390_vfeezfs:
2722 Opcode = SystemZISD::VFEEZ_CC;
2726 case Intrinsic::s390_vfenebs:
2727 case Intrinsic::s390_vfenehs:
2728 case Intrinsic::s390_vfenefs:
2729 Opcode = SystemZISD::VFENE_CC;
2733 case Intrinsic::s390_vfenezbs:
2734 case Intrinsic::s390_vfenezhs:
2735 case Intrinsic::s390_vfenezfs:
2736 Opcode = SystemZISD::VFENEZ_CC;
2740 case Intrinsic::s390_vistrbs:
2741 case Intrinsic::s390_vistrhs:
2742 case Intrinsic::s390_vistrfs:
2743 Opcode = SystemZISD::VISTR_CC;
2747 case Intrinsic::s390_vstrcbs:
2748 case Intrinsic::s390_vstrchs:
2749 case Intrinsic::s390_vstrcfs:
2750 Opcode = SystemZISD::VSTRC_CC;
2754 case Intrinsic::s390_vstrczbs:
2755 case Intrinsic::s390_vstrczhs:
2756 case Intrinsic::s390_vstrczfs:
2757 Opcode = SystemZISD::VSTRCZ_CC;
2761 case Intrinsic::s390_vstrsb:
2762 case Intrinsic::s390_vstrsh:
2763 case Intrinsic::s390_vstrsf:
2764 Opcode = SystemZISD::VSTRS_CC;
2768 case Intrinsic::s390_vstrszb:
2769 case Intrinsic::s390_vstrszh:
2770 case Intrinsic::s390_vstrszf:
2771 Opcode = SystemZISD::VSTRSZ_CC;
2775 case Intrinsic::s390_vfcedbs:
2776 case Intrinsic::s390_vfcesbs:
2777 Opcode = SystemZISD::VFCMPES;
2781 case Intrinsic::s390_vfchdbs:
2782 case Intrinsic::s390_vfchsbs:
2783 Opcode = SystemZISD::VFCMPHS;
2787 case Intrinsic::s390_vfchedbs:
2788 case Intrinsic::s390_vfchesbs:
2789 Opcode = SystemZISD::VFCMPHES;
2793 case Intrinsic::s390_vftcidb:
2794 case Intrinsic::s390_vftcisb:
2795 Opcode = SystemZISD::VFTCI;
2799 case Intrinsic::s390_tdc:
2800 Opcode = SystemZISD::TDC;
2813 unsigned NumOps =
Op.getNumOperands();
2816 Ops.push_back(
Op.getOperand(0));
2818 Ops.push_back(
Op.getOperand(
I));
2820 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2834 unsigned NumOps =
Op.getNumOperands();
2840 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2841 "Unhandled intrinsic with f16 operand.");
2844 Ops.push_back(CurrOper);
2858 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2859 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2860 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2886 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2889 int64_t
Value = ConstOp1->getSExtValue();
2905 if (!
C.Op0.hasOneUse() ||
2912 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2913 if ((NumBits != 8 && NumBits != 16) ||
2914 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2920 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2923 uint64_t Mask = (1 << NumBits) - 1;
2926 int64_t SignedValue = ConstOp1->getSExtValue();
2933 }
else if (NumBits == 8) {
2959 if (
C.Op0.getValueType() != MVT::i32 ||
2960 Load->getExtensionType() != ExtType) {
2962 Load->getBasePtr(), Load->getPointerInfo(),
2963 Load->getMemoryVT(), Load->getAlign(),
2964 Load->getMemOperand()->getFlags());
2970 if (
C.Op1.getValueType() != MVT::i32 ||
2971 Value != ConstOp1->getZExtValue())
2981 if (Load->getMemoryVT() == MVT::i8)
2984 switch (Load->getExtensionType()) {
3001 if (
C.Op0.getValueType() == MVT::i128)
3003 if (
C.Op0.getValueType() == MVT::f128)
3015 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3044 unsigned Opcode0 =
C.Op0.getOpcode();
3051 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3066 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3067 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3089 if (C1 && C1->isZero()) {
3108 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3111 if (C1 && C1->getZExtValue() == 32) {
3112 SDValue ShlOp0 =
C.Op0.getOperand(0);
3131 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3134 C.Op1->getAsZExtVal() == 0) {
3136 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3137 C.Op0.getValueSizeInBits().getFixedValue()) {
3138 unsigned Type = L->getExtensionType();
3141 C.Op0 =
C.Op0.getOperand(0);
3155 uint64_t Amount = Shift->getZExtValue();
3156 if (Amount >=
N.getValueSizeInBits())
3171 unsigned ICmpType) {
3172 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3194 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3200 if (EffectivelyUnsigned && CmpVal <
Low) {
3208 if (CmpVal == Mask) {
3214 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3220 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3228 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3234 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3263 if (
C.Op0.getValueType() == MVT::i128) {
3269 if (Mask && Mask->getAPIntValue() == 0) {
3270 C.Opcode = SystemZISD::VTM;
3287 uint64_t CmpVal = ConstOp1->getZExtValue();
3294 NewC.Op0 =
C.Op0.getOperand(0);
3295 NewC.Op1 =
C.Op0.getOperand(1);
3299 MaskVal = Mask->getZExtValue();
3319 MaskVal = -(CmpVal & -CmpVal);
3328 unsigned NewCCMask, ShiftVal;
3332 (MaskVal >> ShiftVal != 0) &&
3333 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3335 MaskVal >> ShiftVal,
3339 MaskVal >>= ShiftVal;
3343 (MaskVal << ShiftVal != 0) &&
3344 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3346 MaskVal << ShiftVal,
3350 MaskVal <<= ShiftVal;
3359 C.Opcode = SystemZISD::TM;
3361 if (Mask && Mask->getZExtValue() == MaskVal)
3366 C.CCMask = NewCCMask;
3372 if (
C.Opcode != SystemZISD::ICMP)
3374 if (
C.Op0.getValueType() != MVT::i128)
3385 Src = Src.getOperand(0);
3388 unsigned Opcode = 0;
3389 if (Src.hasOneUse()) {
3390 switch (Src.getOpcode()) {
3391 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3392 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3393 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3394 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3395 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3396 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3402 C.Op0 = Src->getOperand(0);
3403 C.Op1 = Src->getOperand(1);
3407 C.CCMask ^=
C.CCValid;
3419 C.Opcode = SystemZISD::VICMPES;
3431 bool Swap =
false, Invert =
false;
3443 C.Opcode = SystemZISD::UCMP128HI;
3445 C.Opcode = SystemZISD::SCMP128HI;
3450 C.CCMask ^=
C.CCValid;
3461 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3464 if ((~Known.
Zero).getZExtValue() & ~Mask->getZExtValue())
3467 C.Op0 =
C.Op0.getOperand(0);
3479 C.CCValid = CCValid;
3482 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3485 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3489 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3492 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3496 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3499 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3502 C.CCMask &= CCValid;
3510 bool IsSignaling =
false) {
3513 unsigned Opcode, CCValid;
3525 Comparison
C(CmpOp0, CmpOp1, Chain);
3527 if (
C.Op0.getValueType().isFloatingPoint()) {
3530 C.Opcode = SystemZISD::FCMP;
3531 else if (!IsSignaling)
3532 C.Opcode = SystemZISD::STRICT_FCMP;
3534 C.Opcode = SystemZISD::STRICT_FCMPS;
3539 C.Opcode = SystemZISD::ICMP;
3574 if (!
C.Op1.getNode()) {
3576 switch (
C.Op0.getOpcode()) {
3587 if (
C.Opcode == SystemZISD::ICMP)
3588 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3590 if (
C.Opcode == SystemZISD::TM) {
3593 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3596 if (
C.Opcode == SystemZISD::VICMPES ||
3597 C.Opcode == SystemZISD::VICMPHS ||
3598 C.Opcode == SystemZISD::VICMPHLS ||
3599 C.Opcode == SystemZISD::VFCMPES ||
3600 C.Opcode == SystemZISD::VFCMPHS ||
3601 C.Opcode == SystemZISD::VFCMPHES) {
3602 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3609 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3611 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3620 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3621 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3646 unsigned CCValid,
unsigned CCMask) {
3651 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3729 int Mask[] = { Start, -1, Start + 1, -1 };
3733 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3735 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3749 !Subtarget.hasVectorEnhancements1()) {
3755 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3768 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3771 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3772 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3774 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3787 bool IsSignaling)
const {
3790 assert (!IsSignaling || Chain);
3793 bool Invert =
false;
3801 assert(IsFP &&
"Unexpected integer comparison");
3803 DL, VT, CmpOp1, CmpOp0, Chain);
3805 DL, VT, CmpOp0, CmpOp1, Chain);
3809 LT.getValue(1),
GE.getValue(1));
3818 assert(IsFP &&
"Unexpected integer comparison");
3820 DL, VT, CmpOp1, CmpOp0, Chain);
3822 DL, VT, CmpOp0, CmpOp1, Chain);
3826 LT.getValue(1),
GT.getValue(1));
3847 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3851 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3856 Chain =
Cmp.getValue(1);
3864 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3877 EVT VT =
Op.getValueType();
3879 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3888 bool IsSignaling)
const {
3894 EVT VT =
Op.getNode()->getValueType(0);
3896 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3897 Chain, IsSignaling);
3919 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
3953 C.CCMask ^=
C.CCValid;
3961 Op = SystemZISD::VICMPE;
3965 Op = SystemZISD::VICMPHL;
3967 Op = SystemZISD::VICMPH;
4006 C.Op1->getAsZExtVal() == 0) {
4013 if (Subtarget.hasVectorEnhancements3() &&
4014 C.Opcode == SystemZISD::ICMP &&
4015 C.Op0.getValueType() == MVT::i128 &&
4025 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4031 const GlobalValue *GV =
Node->getGlobal();
4037 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4040 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4059 }
else if (Subtarget.isTargetELF()) {
4064 }
else if (Subtarget.isTargetzOS()) {
4095 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4100 Ops.push_back(Chain);
4102 Node->getValueType(0),
4111 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4112 const uint32_t *
Mask =
4114 assert(Mask &&
"Missing call preserved mask for calling convention");
4118 Ops.push_back(Glue);
4121 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4129SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4153 const GlobalValue *GV =
Node->getGlobal();
4161 SDValue TP = lowerThreadPointer(
DL, DAG);
4168 SystemZConstantPoolValue *CPV =
4177 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4183 SystemZConstantPoolValue *CPV =
4192 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4197 SystemZMachineFunctionInfo* MFI =
4226 SystemZConstantPoolValue *CPV =
4260 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4277 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4282 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4284 MachineFrameInfo &MFI = MF.getFrameInfo();
4288 unsigned Depth =
Op.getConstantOperandVal(0);
4295 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4300 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4306 MachinePointerInfo());
4321 unsigned Depth =
Op.getConstantOperandVal(0);
4326 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4329 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4330 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4331 int Offset = TFL->getReturnAddressOffset(MF);
4335 MachinePointerInfo());
4340 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4342 &SystemZ::GR64BitRegClass);
4350 EVT InVT =
In.getValueType();
4351 EVT ResVT =
Op.getValueType();
4359 LoadN->getBasePtr(), LoadN->getMemOperand());
4365 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4367 if (Subtarget.hasHighWord()) {
4371 MVT::i64,
SDValue(U64, 0), In);
4379 DL, MVT::f32, Out64);
4381 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4384 MVT::f64,
SDValue(U64, 0), In);
4386 if (Subtarget.hasHighWord())
4399 if (Subtarget.isTargetXPLINK64())
4400 return lowerVASTART_XPLINK(
Op, DAG);
4402 return lowerVASTART_ELF(
Op, DAG);
4408 SystemZMachineFunctionInfo *FuncInfo =
4409 MF.
getInfo<SystemZMachineFunctionInfo>();
4419 MachinePointerInfo(SV));
4425 SystemZMachineFunctionInfo *FuncInfo =
4426 MF.
getInfo<SystemZMachineFunctionInfo>();
4435 const unsigned NumFields = 4;
4446 for (
unsigned I = 0;
I < NumFields; ++
I) {
4451 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4452 MachinePointerInfo(SV,
Offset));
4470 Align(8),
false,
false,
4471 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4472 MachinePointerInfo(SrcSV));
4476SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4478 if (Subtarget.isTargetXPLINK64())
4479 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4481 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4485SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4487 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4497 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4500 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4501 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4507 if (ExtraAlignSpace)
4511 bool IsSigned =
false;
4512 bool DoesNotReturn =
false;
4513 bool IsReturnValueUsed =
false;
4514 EVT VT =
Op.getValueType();
4524 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4536 if (ExtraAlignSpace) {
4548SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4550 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4553 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4562 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4565 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4566 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4577 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4578 MachinePointerInfo());
4581 if (ExtraAlignSpace)
4588 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4589 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4605 if (RequiredAlign > StackAlign) {
4615 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4616 MachinePointerInfo());
4622SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4626 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4631 unsigned Opcode)
const {
4632 EVT VT =
Op.getValueType();
4638 assert(Subtarget.hasMiscellaneousExtensions2());
4643 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4649 EVT VT =
Op.getValueType();
4657 else if (Subtarget.hasMiscellaneousExtensions2())
4662 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4697 EVT VT =
Op.getValueType();
4710 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4718 EVT VT =
Op.getValueType();
4738 EVT VT =
Op.getValueType();
4745 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4750 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4762 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4764 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4801 MVT::i64, HighOp, Low32);
4807 SDNode *
N =
Op.getNode();
4812 if (
N->getValueType(0) == MVT::i128) {
4813 unsigned BaseOp = 0;
4814 unsigned FlagOp = 0;
4815 bool IsBorrow =
false;
4816 switch (
Op.getOpcode()) {
4820 FlagOp = SystemZISD::VACC;
4824 FlagOp = SystemZISD::VSCBI;
4839 unsigned BaseOp = 0;
4840 unsigned CCValid = 0;
4841 unsigned CCMask = 0;
4843 switch (
Op.getOpcode()) {
4846 BaseOp = SystemZISD::SADDO;
4851 BaseOp = SystemZISD::SSUBO;
4856 BaseOp = SystemZISD::UADDO;
4861 BaseOp = SystemZISD::USUBO;
4867 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4871 if (
N->getValueType(1) == MVT::i1)
4897 SDNode *
N =
Op.getNode();
4898 MVT VT =
N->getSimpleValueType(0);
4909 if (VT == MVT::i128) {
4910 unsigned BaseOp = 0;
4911 unsigned FlagOp = 0;
4912 bool IsBorrow =
false;
4913 switch (
Op.getOpcode()) {
4916 BaseOp = SystemZISD::VAC;
4917 FlagOp = SystemZISD::VACCC;
4920 BaseOp = SystemZISD::VSBI;
4921 FlagOp = SystemZISD::VSBCBI;
4940 unsigned BaseOp = 0;
4941 unsigned CCValid = 0;
4942 unsigned CCMask = 0;
4944 switch (
Op.getOpcode()) {
4950 BaseOp = SystemZISD::ADDCARRY;
4958 BaseOp = SystemZISD::SUBCARRY;
4969 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
4973 if (
N->getValueType(1) == MVT::i1)
4981 EVT VT =
Op.getValueType();
4983 Op =
Op.getOperand(0);
5006 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5018 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5031 if (NumSignificantBits == 0)
5037 BitSize = std::min(BitSize, OrigBitSize);
5046 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5048 if (BitSize != OrigBitSize)
5085 EVT RegVT =
Op.getValueType();
5087 return lowerATOMIC_LDST_I128(
Op, DAG);
5088 return lowerLoadF16(
Op, DAG);
5094 if (
Node->getMemoryVT().getSizeInBits() == 128)
5095 return lowerATOMIC_LDST_I128(
Op, DAG);
5096 return lowerStoreF16(
Op, DAG);
5103 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5104 "Only custom lowering i128 or f128.");
5117 EVT WideVT = MVT::i32;
5140 unsigned Opcode)
const {
5144 EVT NarrowVT =
Node->getMemoryVT();
5145 EVT WideVT = MVT::i32;
5146 if (NarrowVT == WideVT)
5153 MachineMemOperand *MMO =
Node->getMemOperand();
5157 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5159 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5164 SDValue AlignedAddr, BitShift, NegBitShift;
5172 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5175 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5176 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5181 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5182 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5202 EVT MemVT =
Node->getMemoryVT();
5203 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5205 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5206 assert(Subtarget.hasInterlockedAccess1() &&
5207 "Should have been expanded by AtomicExpand pass.");
5213 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5214 Node->getMemOperand());
5217 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5228 MachineMemOperand *MMO =
Node->getMemOperand();
5231 if (
Node->getMemoryVT() == MVT::i128) {
5240 EVT NarrowVT =
Node->getMemoryVT();
5241 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5242 if (NarrowVT == WideVT) {
5243 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5244 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5246 DL, Tys,
Ops, NarrowVT, MMO);
5260 SDValue AlignedAddr, BitShift, NegBitShift;
5264 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5265 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5268 VTList,
Ops, NarrowVT, MMO);
5282SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5305 auto *Regs = Subtarget.getSpecialRegisters();
5308 "in GHC calling convention");
5310 Regs->getStackPointerRegister(),
Op.getValueType());
5316 auto *Regs = Subtarget.getSpecialRegisters();
5317 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5321 "in GHC calling convention");
5328 if (StoreBackchain) {
5330 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5331 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5332 MachinePointerInfo());
5335 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5338 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5339 MachinePointerInfo());
5346 bool IsData =
Op.getConstantOperandVal(4);
5349 return Op.getOperand(0);
5352 bool IsWrite =
Op.getConstantOperandVal(2);
5359 Node->getMemoryVT(),
Node->getMemOperand());
5363SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5365 unsigned Opcode, CCValid;
5367 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5378SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5380 unsigned Opcode, CCValid;
5383 if (
Op->getNumValues() == 1)
5385 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5390 unsigned Id =
Op.getConstantOperandVal(0);
5392 case Intrinsic::thread_pointer:
5393 return lowerThreadPointer(SDLoc(
Op), DAG);
5395 case Intrinsic::s390_vpdi:
5396 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5397 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5399 case Intrinsic::s390_vperm:
5400 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5401 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5403 case Intrinsic::s390_vuphb:
5404 case Intrinsic::s390_vuphh:
5405 case Intrinsic::s390_vuphf:
5406 case Intrinsic::s390_vuphg:
5407 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5410 case Intrinsic::s390_vuplhb:
5411 case Intrinsic::s390_vuplhh:
5412 case Intrinsic::s390_vuplhf:
5413 case Intrinsic::s390_vuplhg:
5414 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5417 case Intrinsic::s390_vuplb:
5418 case Intrinsic::s390_vuplhw:
5419 case Intrinsic::s390_vuplf:
5420 case Intrinsic::s390_vuplg:
5421 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5424 case Intrinsic::s390_vupllb:
5425 case Intrinsic::s390_vupllh:
5426 case Intrinsic::s390_vupllf:
5427 case Intrinsic::s390_vupllg:
5428 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5431 case Intrinsic::s390_vsumb:
5432 case Intrinsic::s390_vsumh:
5433 case Intrinsic::s390_vsumgh:
5434 case Intrinsic::s390_vsumgf:
5435 case Intrinsic::s390_vsumqf:
5436 case Intrinsic::s390_vsumqg:
5437 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5438 Op.getOperand(1),
Op.getOperand(2));
5440 case Intrinsic::s390_vaq:
5442 Op.getOperand(1),
Op.getOperand(2));
5443 case Intrinsic::s390_vaccb:
5444 case Intrinsic::s390_vacch:
5445 case Intrinsic::s390_vaccf:
5446 case Intrinsic::s390_vaccg:
5447 case Intrinsic::s390_vaccq:
5448 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5449 Op.getOperand(1),
Op.getOperand(2));
5450 case Intrinsic::s390_vacq:
5451 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5452 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5453 case Intrinsic::s390_vacccq:
5454 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5455 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5457 case Intrinsic::s390_vsq:
5459 Op.getOperand(1),
Op.getOperand(2));
5460 case Intrinsic::s390_vscbib:
5461 case Intrinsic::s390_vscbih:
5462 case Intrinsic::s390_vscbif:
5463 case Intrinsic::s390_vscbig:
5464 case Intrinsic::s390_vscbiq:
5465 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5466 Op.getOperand(1),
Op.getOperand(2));
5467 case Intrinsic::s390_vsbiq:
5468 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5469 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5470 case Intrinsic::s390_vsbcbiq:
5471 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5472 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5474 case Intrinsic::s390_vmhb:
5475 case Intrinsic::s390_vmhh:
5476 case Intrinsic::s390_vmhf:
5477 case Intrinsic::s390_vmhg:
5478 case Intrinsic::s390_vmhq:
5480 Op.getOperand(1),
Op.getOperand(2));
5481 case Intrinsic::s390_vmlhb:
5482 case Intrinsic::s390_vmlhh:
5483 case Intrinsic::s390_vmlhf:
5484 case Intrinsic::s390_vmlhg:
5485 case Intrinsic::s390_vmlhq:
5487 Op.getOperand(1),
Op.getOperand(2));
5489 case Intrinsic::s390_vmahb:
5490 case Intrinsic::s390_vmahh:
5491 case Intrinsic::s390_vmahf:
5492 case Intrinsic::s390_vmahg:
5493 case Intrinsic::s390_vmahq:
5494 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5495 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5496 case Intrinsic::s390_vmalhb:
5497 case Intrinsic::s390_vmalhh:
5498 case Intrinsic::s390_vmalhf:
5499 case Intrinsic::s390_vmalhg:
5500 case Intrinsic::s390_vmalhq:
5501 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5502 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5504 case Intrinsic::s390_vmeb:
5505 case Intrinsic::s390_vmeh:
5506 case Intrinsic::s390_vmef:
5507 case Intrinsic::s390_vmeg:
5508 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5509 Op.getOperand(1),
Op.getOperand(2));
5510 case Intrinsic::s390_vmleb:
5511 case Intrinsic::s390_vmleh:
5512 case Intrinsic::s390_vmlef:
5513 case Intrinsic::s390_vmleg:
5514 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5515 Op.getOperand(1),
Op.getOperand(2));
5516 case Intrinsic::s390_vmob:
5517 case Intrinsic::s390_vmoh:
5518 case Intrinsic::s390_vmof:
5519 case Intrinsic::s390_vmog:
5520 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5521 Op.getOperand(1),
Op.getOperand(2));
5522 case Intrinsic::s390_vmlob:
5523 case Intrinsic::s390_vmloh:
5524 case Intrinsic::s390_vmlof:
5525 case Intrinsic::s390_vmlog:
5526 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5527 Op.getOperand(1),
Op.getOperand(2));
5529 case Intrinsic::s390_vmaeb:
5530 case Intrinsic::s390_vmaeh:
5531 case Intrinsic::s390_vmaef:
5532 case Intrinsic::s390_vmaeg:
5534 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5535 Op.getOperand(1),
Op.getOperand(2)),
5537 case Intrinsic::s390_vmaleb:
5538 case Intrinsic::s390_vmaleh:
5539 case Intrinsic::s390_vmalef:
5540 case Intrinsic::s390_vmaleg:
5542 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5543 Op.getOperand(1),
Op.getOperand(2)),
5545 case Intrinsic::s390_vmaob:
5546 case Intrinsic::s390_vmaoh:
5547 case Intrinsic::s390_vmaof:
5548 case Intrinsic::s390_vmaog:
5550 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5551 Op.getOperand(1),
Op.getOperand(2)),
5553 case Intrinsic::s390_vmalob:
5554 case Intrinsic::s390_vmaloh:
5555 case Intrinsic::s390_vmalof:
5556 case Intrinsic::s390_vmalog:
5558 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5559 Op.getOperand(1),
Op.getOperand(2)),
5580 { SystemZISD::MERGE_HIGH, 8,
5581 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5583 { SystemZISD::MERGE_HIGH, 4,
5584 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5586 { SystemZISD::MERGE_HIGH, 2,
5587 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5589 { SystemZISD::MERGE_HIGH, 1,
5590 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5592 { SystemZISD::MERGE_LOW, 8,
5593 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5595 { SystemZISD::MERGE_LOW, 4,
5596 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5598 { SystemZISD::MERGE_LOW, 2,
5599 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5601 { SystemZISD::MERGE_LOW, 1,
5602 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5604 { SystemZISD::PACK, 4,
5605 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5607 { SystemZISD::PACK, 2,
5608 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5610 { SystemZISD::PACK, 1,
5611 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5613 { SystemZISD::PERMUTE_DWORDS, 4,
5614 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5616 { SystemZISD::PERMUTE_DWORDS, 1,
5617 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5631 OpNo0 = OpNo1 = OpNos[1];
5632 }
else if (OpNos[1] < 0) {
5633 OpNo0 = OpNo1 = OpNos[0];
5651 unsigned &OpNo0,
unsigned &OpNo1) {
5652 int OpNos[] = { -1, -1 };
5665 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5667 OpNos[ModelOpNo] = RealOpNo;
5675 unsigned &OpNo0,
unsigned &OpNo1) {
5692 int Elt = Bytes[From];
5695 Transform[From] = -1;
5697 while (
P.Bytes[To] != Elt) {
5702 Transform[From] = To;
5726 Bytes.
resize(NumElements * BytesPerElement, -1);
5727 for (
unsigned I = 0;
I < NumElements; ++
I) {
5728 int Index = VSN->getMaskElt(
I);
5730 for (
unsigned J = 0; J < BytesPerElement; ++J)
5731 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5735 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5738 Bytes.
resize(NumElements * BytesPerElement, -1);
5739 for (
unsigned I = 0;
I < NumElements; ++
I)
5740 for (
unsigned J = 0; J < BytesPerElement; ++J)
5741 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5752 unsigned BytesPerElement,
int &
Base) {
5754 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5755 if (Bytes[Start +
I] >= 0) {
5756 unsigned Elem = Bytes[Start +
I];
5760 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5762 }
else if (
unsigned(
Base) != Elem -
I)
5775 unsigned &StartIndex,
unsigned &OpNo0,
5777 int OpNos[] = { -1, -1 };
5779 for (
unsigned I = 0;
I < 16; ++
I) {
5780 int Index = Bytes[
I];
5786 Shift = ExpectedShift;
5787 else if (Shift != ExpectedShift)
5791 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5793 OpNos[ModelOpNo] = RealOpNo;
5806 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5807 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5815 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5817 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5818 }
else if (
P.Opcode == SystemZISD::PACK) {
5821 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5830 N =
N->getOperand(0);
5833 return Op->getZExtValue() == 0;
5839 for (
unsigned I = 0;
I < Num ;
I++)
5851 for (
unsigned I = 0;
I < 2; ++
I)
5855 unsigned StartIndex, OpNo0, OpNo1;
5857 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5864 if (ZeroVecIdx != UINT32_MAX) {
5865 bool MaskFirst =
true;
5870 if (OpNo == ZeroVecIdx &&
I == 0) {
5875 if (OpNo != ZeroVecIdx && Byte == 0) {
5882 if (ZeroIdx != -1) {
5885 if (Bytes[
I] >= 0) {
5888 if (OpNo == ZeroVecIdx)
5900 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5903 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5915 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5921struct GeneralShuffle {
5922 GeneralShuffle(EVT vt)
5923 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
5927 void tryPrepareForUnpack();
5928 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
5943 unsigned UnpackFromEltSize;
5950void GeneralShuffle::addUndef() {
5952 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5953 Bytes.push_back(-1);
5962bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
5968 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
5973 if (FromBytesPerElement < BytesPerElement)
5977 (FromBytesPerElement - BytesPerElement));
5980 while (
Op.getNode()) {
5982 Op =
Op.getOperand(0);
5998 }
else if (
Op.isUndef()) {
6007 for (; OpNo <
Ops.size(); ++OpNo)
6008 if (
Ops[OpNo] ==
Op)
6010 if (OpNo ==
Ops.size())
6015 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6016 Bytes.push_back(
Base +
I);
6025 if (
Ops.size() == 0)
6029 tryPrepareForUnpack();
6032 if (
Ops.size() == 1)
6044 unsigned Stride = 1;
6045 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6046 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6056 else if (OpNo ==
I + Stride)
6067 if (NewBytes[J] >= 0) {
6069 "Invalid double permute");
6072 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6078 if (NewBytes[J] >= 0)
6094 unsigned OpNo0, OpNo1;
6098 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6103 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6110 dbgs() << Msg.c_str() <<
" { ";
6111 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6112 dbgs() << Bytes[
I] <<
" ";
6120void GeneralShuffle::tryPrepareForUnpack() {
6122 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6127 if (
Ops.size() > 2 &&
6132 UnpackFromEltSize = 1;
6133 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6134 bool MatchUnpack =
true;
6137 unsigned ToEltSize = UnpackFromEltSize * 2;
6138 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6141 if (Bytes[Elt] != -1) {
6143 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6144 MatchUnpack =
false;
6150 if (
Ops.size() == 2) {
6152 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6154 if (SrcBytes[i] == -1)
6156 if (SrcBytes[i] % 16 !=
int(i))
6157 CanUseUnpackHigh =
false;
6159 CanUseUnpackLow =
false;
6160 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6161 UnpackFromEltSize = UINT_MAX;
6165 if (!CanUseUnpackHigh)
6171 if (UnpackFromEltSize > 4)
6174 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6175 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6177 dumpBytes(Bytes,
"Original Bytes vector:"););
6186 Elt += UnpackFromEltSize;
6187 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6188 Bytes[
B] = Bytes[Elt];
6196 Ops.erase(&
Ops[ZeroVecOpNo]);
6198 if (Bytes[
I] >= 0) {
6200 if (OpNo > ZeroVecOpNo)
6211 if (!unpackWasPrepared())
6213 unsigned InBits = UnpackFromEltSize * 8;
6217 unsigned OutBits = InBits * 2;
6220 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6221 : SystemZISD::UNPACKL_HIGH,
6222 DL, OutVT, PackedOp);
6227 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6228 if (!
Op.getOperand(
I).isUndef())
6244 if (
Value.isUndef())
6256 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6259 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6260 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6281 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6297 GeneralShuffle GS(VT);
6299 bool FoundOne =
false;
6300 for (
unsigned I = 0;
I < NumElements; ++
I) {
6303 Op =
Op.getOperand(0);
6306 unsigned Elem =
Op.getConstantOperandVal(1);
6307 if (!GS.add(
Op.getOperand(0), Elem))
6310 }
else if (
Op.isUndef()) {
6324 if (!ResidueOps.
empty()) {
6325 while (ResidueOps.
size() < NumElements)
6327 for (
auto &
Op : GS.Ops) {
6328 if (!
Op.getNode()) {
6334 return GS.getNode(DAG,
SDLoc(BVN));
6337bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6343 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6354 unsigned int NumElements = Elems.
size();
6355 unsigned int Count = 0;
6356 for (
auto Elem : Elems) {
6357 if (!Elem.isUndef()) {
6360 else if (Elem != Single) {
6380 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6381 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6384 bool AllLoads =
true;
6385 for (
auto Elem : Elems)
6386 if (!isVectorElementLoad(Elem)) {
6392 if (VT == MVT::v2i64 && !AllLoads)
6396 if (VT == MVT::v2f64 && !AllLoads)
6406 if (VT == MVT::v4f32 && !AllLoads) {
6415 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6420 DL, MVT::v2i64, Op01, Op23);
6428 unsigned NumConstants = 0;
6429 for (
unsigned I = 0;
I < NumElements; ++
I) {
6443 if (NumConstants > 0) {
6444 for (
unsigned I = 0;
I < NumElements; ++
I)
6455 std::map<const SDNode*, unsigned> UseCounts;
6456 SDNode *LoadMaxUses =
nullptr;
6457 for (
unsigned I = 0;
I < NumElements; ++
I)
6458 if (isVectorElementLoad(Elems[
I])) {
6459 SDNode *Ld = Elems[
I].getNode();
6460 unsigned Count = ++UseCounts[Ld];
6461 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6464 if (LoadMaxUses !=
nullptr) {
6465 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6469 unsigned I1 = NumElements / 2 - 1;
6470 unsigned I2 = NumElements - 1;
6471 bool Def1 = !Elems[
I1].isUndef();
6472 bool Def2 = !Elems[I2].isUndef();
6486 for (
unsigned I = 0;
I < NumElements; ++
I)
6487 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6497 EVT VT =
Op.getValueType();
6499 if (BVN->isConstant()) {
6500 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6518 for (
unsigned I = 0;
I < NumElements; ++
I)
6520 return buildVector(DAG,
DL, VT,
Ops);
6527 EVT VT =
Op.getValueType();
6530 if (VSN->isSplat()) {
6532 unsigned Index = VSN->getSplatIndex();
6534 "Splat index should be defined and in first operand");
6540 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6544 GeneralShuffle
GS(VT);
6545 for (
unsigned I = 0;
I < NumElements; ++
I) {
6546 int Elt = VSN->getMaskElt(
I);
6549 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6550 unsigned(Elt) % NumElements))
6553 return GS.getNode(DAG, SDLoc(VSN));
6572 EVT VT =
Op.getValueType();
6577 if (VT == MVT::v2f64 &&
6597SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6603 EVT VT =
Op.getValueType();
6608 uint64_t
Index = CIndexN->getZExtValue();
6622SDValue SystemZTargetLowering::
6625 EVT OutVT =
Op.getValueType();
6629 unsigned StartOffset = 0;
6636 ArrayRef<int> ShuffleMask = SVN->
getMask();
6641 if (ToBits == 64 && OutNumElts == 2) {
6642 int NumElem = ToBits / FromBits;
6643 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6649 int StartOffsetCandidate = -1;
6650 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6651 if (ShuffleMask[Elt] == -1)
6653 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6654 if (StartOffsetCandidate == -1)
6655 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6656 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6659 StartOffsetCandidate = -1;
6662 if (StartOffsetCandidate != -1) {
6663 StartOffset = StartOffsetCandidate;
6672 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6673 if (StartOffset >= OutNumElts) {
6674 Opcode = SystemZISD::UNPACK_LOW;
6675 StartOffset -= OutNumElts;
6677 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6678 }
while (FromBits != ToBits);
6683SDValue SystemZTargetLowering::
6687 EVT OutVT =
Op.getValueType();
6691 unsigned NumInPerOut = InNumElts / OutNumElts;
6696 SmallVector<int, 16>
Mask(InNumElts);
6697 unsigned ZeroVecElt = InNumElts;
6698 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6699 unsigned MaskElt = PackedElt * NumInPerOut;
6700 unsigned End = MaskElt + NumInPerOut - 1;
6701 for (; MaskElt < End; MaskElt++)
6702 Mask[MaskElt] = ZeroVecElt++;
6703 Mask[MaskElt] = PackedElt;
6710 unsigned ByScalar)
const {
6715 EVT VT =
Op.getValueType();
6720 APInt SplatBits, SplatUndef;
6721 unsigned SplatBitSize;
6725 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6726 ElemBitSize,
true) &&
6727 SplatBitSize == ElemBitSize) {
6730 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6733 BitVector UndefElements;
6739 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6746 if (VSN->isSplat()) {
6747 SDValue VSNOp0 = VSN->getOperand(0);
6748 unsigned Index = VSN->getSplatIndex();
6750 "Splat index should be defined and in first operand");
6757 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6775 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6776 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6779 if (ShiftAmt > 120) {
6783 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6787 SmallVector<int, 16>
Mask(16);
6788 for (
unsigned Elt = 0; Elt < 16; Elt++)
6789 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6791 if ((ShiftAmt & 7) == 0)
6795 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6813 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6814 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6817 if (ShiftAmt > 120) {
6821 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6825 SmallVector<int, 16>
Mask(16);
6826 for (
unsigned Elt = 0; Elt < 16; Elt++)
6827 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6829 if ((ShiftAmt & 7) == 0)
6833 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6845 MVT DstVT =
Op.getSimpleValueType();
6848 unsigned SrcAS =
N->getSrcAddressSpace();
6850 assert(SrcAS !=
N->getDestAddressSpace() &&
6851 "addrspacecast must be between different address spaces");
6859 }
else if (DstVT == MVT::i32) {
6873 if (
In.getSimpleValueType() != MVT::f16)
6880 SDValue Chain,
bool IsStrict)
const {
6881 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
6884 std::tie(Result, Chain) =
6893 bool IsStrict =
Op->isStrictFPOpcode();
6895 MVT VT =
Op.getSimpleValueType();
6896 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6904 if (!Subtarget.hasFPExtension() && !IsSigned)
6915 if (VT == MVT::i128) {
6918 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6928 bool IsStrict =
Op->isStrictFPOpcode();
6930 MVT VT =
Op.getSimpleValueType();
6931 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6936 if (VT == MVT::f16) {
6943 if (!Subtarget.hasFPExtension() && !IsSigned)
6946 if (InVT == MVT::i128) {
6949 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6958 assert(
Op.getSimpleValueType() == MVT::i64 &&
6959 "Expexted to convert i64 to f16.");
6971 assert(
Op.getSimpleValueType() == MVT::f16 &&
6972 "Expected to convert f16 to i64.");
6985 EVT RegVT =
Op.getValueType();
6986 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
6993 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
6995 AtomicLd->getChain(), AtomicLd->getBasePtr(),
6996 AtomicLd->getMemOperand());
7016 Shft, AtomicSt->getBasePtr(),
7017 AtomicSt->getMemOperand());
7027 MVT ResultVT =
Op.getSimpleValueType();
7029 unsigned Check =
Op.getConstantOperandVal(1);
7031 unsigned TDCMask = 0;
7068 MachinePointerInfo MPI =
7074 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7078 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7083 switch (
Op.getOpcode()) {
7085 return lowerFRAMEADDR(
Op, DAG);
7087 return lowerRETURNADDR(
Op, DAG);
7089 return lowerBR_CC(
Op, DAG);
7091 return lowerSELECT_CC(
Op, DAG);
7093 return lowerSETCC(
Op, DAG);
7095 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7097 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7109 return lowerBITCAST(
Op, DAG);
7111 return lowerVASTART(
Op, DAG);
7113 return lowerVACOPY(
Op, DAG);
7115 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7117 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7119 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7121 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7123 return lowerSMUL_LOHI(
Op, DAG);
7125 return lowerUMUL_LOHI(
Op, DAG);
7127 return lowerSDIVREM(
Op, DAG);
7129 return lowerUDIVREM(
Op, DAG);
7134 return lowerXALUO(
Op, DAG);
7137 return lowerUADDSUBO_CARRY(
Op, DAG);
7139 return lowerOR(
Op, DAG);
7141 return lowerCTPOP(
Op, DAG);
7143 return lowerVECREDUCE_ADD(
Op, DAG);
7145 return lowerATOMIC_FENCE(
Op, DAG);
7147 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7149 return lowerATOMIC_STORE(
Op, DAG);
7151 return lowerATOMIC_LOAD(
Op, DAG);
7153 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7155 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7157 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7159 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7161 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7163 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7165 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7167 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7169 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7171 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7173 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7175 return lowerSTACKSAVE(
Op, DAG);
7177 return lowerSTACKRESTORE(
Op, DAG);
7179 return lowerPREFETCH(
Op, DAG);
7181 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7183 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7185 return lowerBUILD_VECTOR(
Op, DAG);
7187 return lowerVECTOR_SHUFFLE(
Op, DAG);
7189 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7191 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7193 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7195 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7197 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7199 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7201 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7203 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7207 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7209 return lowerFSHL(
Op, DAG);
7211 return lowerFSHR(
Op, DAG);
7214 return lowerFP_EXTEND(
Op, DAG);
7219 return lower_FP_TO_INT(
Op, DAG);
7224 return lower_INT_TO_FP(
Op, DAG);
7226 return lowerLoadF16(
Op, DAG);
7228 return lowerStoreF16(
Op, DAG);
7230 return lowerIS_FPCLASS(
Op, DAG);
7232 return lowerGET_ROUNDING(
Op, DAG);
7234 return lowerREADCYCLECOUNTER(
Op, DAG);
7256 &SystemZ::FP128BitRegClass);
7265 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7280 &SystemZ::FP128BitRegClass);
7297 switch (
N->getOpcode()) {
7301 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7304 DL, Tys,
Ops, MVT::i128, MMO);
7307 if (
N->getValueType(0) == MVT::f128)
7321 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7324 DL, Tys,
Ops, MVT::i128, MMO);
7330 MVT::Other, Res), 0);
7342 DL, Tys,
Ops, MVT::i128, MMO);
7356 EVT SrcVT = Src.getValueType();
7357 EVT ResVT =
N->getValueType(0);
7358 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7360 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7361 if (Subtarget.hasVector()) {
7369 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7371 Subtarget.hasVector()
7385 bool IsStrict =
N->isStrictFPOpcode();
7387 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7388 EVT ResVT =
N->getValueType(0);
7390 if (ResVT == MVT::f16) {
7413 bool IsStrict =
N->isStrictFPOpcode();
7415 EVT ResVT =
N->getValueType(0);
7416 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7419 if (InVT == MVT::f16) {
7425 std::tie(InF32, Chain) =
7450bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7451 if (!Subtarget.hasVector())
7465 DAGCombinerInfo &DCI,
7473 unsigned Opcode =
Op.getOpcode();
7476 Op =
Op.getOperand(0);
7478 canTreatAsByteVector(
Op.getValueType())) {
7487 BytesPerElement,
First))
7494 if (Byte % BytesPerElement != 0)
7497 Index = Byte / BytesPerElement;
7501 canTreatAsByteVector(
Op.getValueType())) {
7504 EVT OpVT =
Op.getValueType();
7506 if (OpBytesPerElement < BytesPerElement)
7510 unsigned End = (
Index + 1) * BytesPerElement;
7511 if (End % OpBytesPerElement != 0)
7514 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7515 if (!
Op.getValueType().isInteger()) {
7518 DCI.AddToWorklist(
Op.getNode());
7523 DCI.AddToWorklist(
Op.getNode());
7530 canTreatAsByteVector(
Op.getValueType()) &&
7531 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7533 EVT ExtVT =
Op.getValueType();
7534 EVT OpVT =
Op.getOperand(0).getValueType();
7537 unsigned Byte =
Index * BytesPerElement;
7538 unsigned SubByte =
Byte % ExtBytesPerElement;
7539 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7540 if (SubByte < MinSubByte ||
7541 SubByte + BytesPerElement > ExtBytesPerElement)
7544 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7546 Byte += SubByte - MinSubByte;
7547 if (Byte % BytesPerElement != 0)
7549 Op =
Op.getOperand(0);
7556 if (
Op.getValueType() != VecVT) {
7558 DCI.AddToWorklist(
Op.getNode());
7568SDValue SystemZTargetLowering::combineTruncateExtract(
7577 if (canTreatAsByteVector(VecVT)) {
7581 if (BytesPerElement % TruncBytes == 0) {
7587 unsigned Scale = BytesPerElement / TruncBytes;
7588 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7595 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7596 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7604SDValue SystemZTargetLowering::combineZERO_EXTEND(
7605 SDNode *
N, DAGCombinerInfo &DCI)
const {
7607 SelectionDAG &DAG = DCI.DAG;
7609 EVT VT =
N->getValueType(0);
7610 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7613 if (TrueOp && FalseOp) {
7623 DCI.CombineTo(N0.
getNode(), TruncSelect);
7666 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7684SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7685 SDNode *
N, DAGCombinerInfo &DCI)
const {
7689 SelectionDAG &DAG = DCI.DAG;
7691 EVT VT =
N->getValueType(0);
7705SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7706 SDNode *
N, DAGCombinerInfo &DCI)
const {
7710 SelectionDAG &DAG = DCI.DAG;
7712 EVT VT =
N->getValueType(0);
7719 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7720 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7736SDValue SystemZTargetLowering::combineMERGE(
7737 SDNode *
N, DAGCombinerInfo &DCI)
const {
7738 SelectionDAG &DAG = DCI.DAG;
7739 unsigned Opcode =
N->getOpcode();
7747 if (Op1 ==
N->getOperand(0))
7752 if (ElemBytes <= 4) {
7753 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7754 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7760 DCI.AddToWorklist(Op1.
getNode());
7763 DCI.AddToWorklist(
Op.getNode());
7772 LoPart = HiPart =
nullptr;
7777 if (
Use.getResNo() != 0)
7782 bool IsLoPart =
true;
7807 LoPart = HiPart =
nullptr;
7812 if (
Use.getResNo() != 0)
7818 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7821 switch (
User->getConstantOperandVal(1)) {
7822 case SystemZ::subreg_l64:
7827 case SystemZ::subreg_h64:
7839SDValue SystemZTargetLowering::combineLOAD(
7840 SDNode *
N, DAGCombinerInfo &DCI)
const {
7841 SelectionDAG &DAG = DCI.DAG;
7842 EVT LdVT =
N->getValueType(0);
7846 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7847 if (PtrVT != LoadNodeVT) {
7851 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7852 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7853 LN->getMemOperand());
7863 SDNode *LoPart, *HiPart;
7871 LD->getPointerInfo(),
LD->getBaseAlign(),
7872 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7874 DCI.CombineTo(HiPart, EltLoad,
true);
7881 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7882 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7884 DCI.CombineTo(LoPart, EltLoad,
true);
7891 DCI.AddToWorklist(Chain.
getNode());
7906 for (SDUse &Use :
N->uses()) {
7907 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
7911 }
else if (
Use.getResNo() == 0)
7914 if (!Replicate || OtherUses.
empty())
7920 for (SDNode *U : OtherUses) {
7923 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
7929bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
7930 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
7932 if (Subtarget.hasVectorEnhancements2())
7933 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
7945 for (
unsigned i = 0; i < NumElts; ++i) {
7946 if (M[i] < 0)
continue;
7947 if ((
unsigned) M[i] != NumElts - 1 - i)
7955 for (
auto *U : StoredVal->
users()) {
7957 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8016SDValue SystemZTargetLowering::combineSTORE(
8017 SDNode *
N, DAGCombinerInfo &DCI)
const {
8018 SelectionDAG &DAG = DCI.DAG;
8021 EVT MemVT = SN->getMemoryVT();
8025 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8026 if (PtrVT != StoreNodeVT) {
8030 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8031 SN->getPointerInfo(), SN->getBaseAlign(),
8032 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8040 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8042 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8043 DCI.AddToWorklist(
Value.getNode());
8047 SN->getBasePtr(), SN->getMemoryVT(),
8048 SN->getMemOperand());
8052 if (!SN->isTruncatingStore() &&
8068 Ops, MemVT, SN->getMemOperand());
8071 if (!SN->isTruncatingStore() &&
8074 Subtarget.hasVectorEnhancements2()) {
8076 ArrayRef<int> ShuffleMask = SVN->
getMask();
8084 Ops, MemVT, SN->getMemOperand());
8089 if (!SN->isTruncatingStore() &&
8092 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8096 Ops, MemVT, SN->getMemOperand());
8106 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8107 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8109 SN->getChain(),
DL, LoPart,
8111 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8112 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8130 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8132 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8136 APInt Val =
C->getAPIntValue();
8139 assert(SN->isTruncatingStore() &&
8140 "Non-truncating store and immediate value does not fit?");
8141 Val = Val.
trunc(TotBytes * 8);
8144 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8145 if (VCI.isVectorConstantLegal(Subtarget) &&
8146 VCI.Opcode == SystemZISD::REPLICATE) {
8154 auto FindReplicatedReg = [&](
SDValue MulOp) {
8155 EVT MulVT = MulOp.getValueType();
8156 if (MulOp->getOpcode() ==
ISD::MUL &&
8157 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8161 WordVT =
LHS->getOperand(0).getValueType();
8168 SystemZVectorConstantInfo VCI(
8170 if (VCI.isVectorConstantLegal(Subtarget) &&
8171 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8172 WordVT == VCI.VecVT.getScalarType())
8184 FindReplicatedReg(SplatVal);
8189 FindReplicatedReg(Op1);
8194 "Bad type handling");
8198 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8199 SN->getBasePtr(), SN->getMemOperand());
8206SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8207 SDNode *
N, DAGCombinerInfo &DCI)
const {
8208 SelectionDAG &DAG = DCI.DAG;
8211 N->getOperand(0).hasOneUse() &&
8212 Subtarget.hasVectorEnhancements2()) {
8214 ArrayRef<int> ShuffleMask = SVN->
getMask();
8227 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8231 DCI.CombineTo(
N, ESLoad);
8235 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8245SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8246 SDNode *
N, DAGCombinerInfo &DCI)
const {
8247 SelectionDAG &DAG = DCI.DAG;
8249 if (!Subtarget.hasVector())
8255 Op.getValueType().isVector() &&
8256 Op.getOperand(0).getValueType().isVector() &&
8257 Op.getValueType().getVectorNumElements() ==
8258 Op.getOperand(0).getValueType().getVectorNumElements())
8259 Op =
Op.getOperand(0);
8263 EVT VecVT =
Op.getValueType();
8266 Op.getOperand(0),
N->getOperand(1));
8267 DCI.AddToWorklist(
Op.getNode());
8269 if (EltVT !=
N->getValueType(0)) {
8270 DCI.AddToWorklist(
Op.getNode());
8280 if (canTreatAsByteVector(VecVT))
8281 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8282 IndexN->getZExtValue(), DCI,
false);
8287SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8288 SDNode *
N, DAGCombinerInfo &DCI)
const {
8289 SelectionDAG &DAG = DCI.DAG;
8291 if (
N->getOperand(0) ==
N->getOperand(1))
8292 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8302 if (Chain1 == Chain2)
8310SDValue SystemZTargetLowering::combineFP_ROUND(
8311 SDNode *
N, DAGCombinerInfo &DCI)
const {
8313 if (!Subtarget.hasVector())
8322 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8323 SelectionDAG &DAG = DCI.DAG;
8325 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8331 for (
auto *U : Vec->
users()) {
8332 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8334 U->getOperand(0) == Vec &&
8336 U->getConstantOperandVal(1) == 1) {
8338 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8342 if (
N->isStrictFPOpcode()) {
8346 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8347 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8350 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8352 DCI.AddToWorklist(VRound.
getNode());
8356 DCI.AddToWorklist(Extract1.
getNode());
8362 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8365 N->getVTList(), Extract0, Chain);
8374SDValue SystemZTargetLowering::combineFP_EXTEND(
8375 SDNode *
N, DAGCombinerInfo &DCI)
const {
8377 if (!Subtarget.hasVector())
8386 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8387 SelectionDAG &DAG = DCI.DAG;
8389 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8395 for (
auto *U : Vec->
users()) {
8396 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8398 U->getOperand(0) == Vec &&
8400 U->getConstantOperandVal(1) == 2) {
8402 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8406 if (
N->isStrictFPOpcode()) {
8410 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8411 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8414 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8416 DCI.AddToWorklist(VExtend.
getNode());
8420 DCI.AddToWorklist(Extract1.
getNode());
8426 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8429 N->getVTList(), Extract0, Chain);
8438SDValue SystemZTargetLowering::combineINT_TO_FP(
8439 SDNode *
N, DAGCombinerInfo &DCI)
const {
8442 SelectionDAG &DAG = DCI.DAG;
8444 unsigned Opcode =
N->getOpcode();
8445 EVT OutVT =
N->getValueType(0);
8449 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8455 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8456 OutScalarBits <= 64) {
8460 unsigned ExtOpcode =
8463 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8468SDValue SystemZTargetLowering::combineFCOPYSIGN(
8469 SDNode *
N, DAGCombinerInfo &DCI)
const {
8470 SelectionDAG &DAG = DCI.DAG;
8471 EVT VT =
N->getValueType(0);
8484SDValue SystemZTargetLowering::combineBSWAP(
8485 SDNode *
N, DAGCombinerInfo &DCI)
const {
8486 SelectionDAG &DAG = DCI.DAG;
8489 N->getOperand(0).hasOneUse() &&
8490 canLoadStoreByteSwapped(
N->getValueType(0))) {
8499 EVT LoadVT =
N->getValueType(0);
8500 if (LoadVT == MVT::i16)
8505 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8509 if (
N->getValueType(0) == MVT::i16)
8514 DCI.CombineTo(
N, ResVal);
8518 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8527 Op.getValueType().isVector() &&
8528 Op.getOperand(0).getValueType().isVector() &&
8529 Op.getValueType().getVectorNumElements() ==
8530 Op.getOperand(0).getValueType().getVectorNumElements())
8531 Op =
Op.getOperand(0);
8543 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8545 EVT VecVT =
N->getValueType(0);
8549 DCI.AddToWorklist(Vec.
getNode());
8553 DCI.AddToWorklist(Elt.
getNode());
8556 DCI.AddToWorklist(Vec.
getNode());
8558 DCI.AddToWorklist(Elt.
getNode());
8566 if (SV &&
Op.hasOneUse()) {
8574 EVT VecVT =
N->getValueType(0);
8577 DCI.AddToWorklist(Op0.
getNode());
8581 DCI.AddToWorklist(Op1.
getNode());
8584 DCI.AddToWorklist(Op0.
getNode());
8586 DCI.AddToWorklist(Op1.
getNode());
8594SDValue SystemZTargetLowering::combineSETCC(
8595 SDNode *
N, DAGCombinerInfo &DCI)
const {
8596 SelectionDAG &DAG = DCI.DAG;
8602 EVT VT =
N->getValueType(0);
8612 Src.getValueType().isFixedLengthVector() &&
8613 Src.getValueType().getScalarType() == MVT::i1) {
8614 EVT CmpVT = Src.getOperand(0).getValueType();
8634 case SystemZISD::IPM:
8639 case SystemZISD::SELECT_CCMASK: {
8641 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8642 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8645 return std::make_pair(OpCC, OpCCValid);
8650 int CCValidVal = CCValid->getZExtValue();
8651 return std::make_pair(Op4CCReg, CCValidVal);
8662 return std::make_pair(Op0CC, Op0CCValid);
8678 return {Val, Val, Val, Val};
8679 case SystemZISD::IPM: {
8684 for (
auto CC : {0, 1, 2, 3})
8687 return ShiftedCCVals;
8689 case SystemZISD::SELECT_CCMASK: {
8693 if (!CCValid || !CCMask)
8696 int CCValidVal = CCValid->getZExtValue();
8697 int CCMaskVal = CCMask->getZExtValue();
8707 if (TrueSDVals.empty() || FalseSDVals.empty())
8710 for (
auto &CCVal : {0, 1, 2, 3})
8711 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8713 : FalseSDVals[CCVal]);
8714 return MergedSDVals;
8731 if (Op0SDVals.empty() || Op1SDVals.empty())
8734 for (
auto CCVal : {0, 1, 2, 3})
8736 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8737 return BinaryOpSDVals;
8748 auto *CCNode = CCReg.
getNode();
8752 if (CCNode->getOpcode() == SystemZISD::TM) {
8755 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8758 if (!Op0Node || !Op1Node)
8760 auto Op0APVal = Op0Node->getAPIntValue();
8761 auto Op1APVal = Op1Node->getAPIntValue();
8762 auto Result = Op0APVal & Op1APVal;
8763 bool AllOnes = Result == Op1APVal;
8764 bool AllZeros = Result == 0;
8765 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits()] != 0;
8766 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8770 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8775 if (Op0SDVals.empty() || Op1SDVals.empty())
8778 for (
auto CC : {0, 1, 2, 3}) {
8779 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8783 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8785 NewCCMask &= Op0CCValid;
8788 CCValid = Op0CCValid;
8791 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8798 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8802 if (Op0SDVals.empty() || Op1SDVals.empty())
8806 auto CmpTypeVal = CmpType->getZExtValue();
8807 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8811 if (!Op0Node || !Op1Node)
8813 auto Op0APVal = Op0Node->getAPIntValue();
8814 auto Op1APVal = Op1Node->getAPIntValue();
8816 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8817 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8820 for (
auto CC : {0, 1, 2, 3}) {
8821 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8825 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8827 NewCCMask &= Op0CCValid;
8830 CCValid = Op0CCValid;
8841 const Value *Rhs)
const {
8842 const auto isFlagOutOpCC = [](
const Value *V) {
8844 const Value *RHSVal;
8851 if (CB->isInlineAsm()) {
8853 return IA && IA->getConstraintString().contains(
"{@cc}");
8864 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8867 return {-1, -1, -1};
8871 DAGCombinerInfo &DCI)
const {
8877 if (!CCValid || !CCMask)
8880 int CCValidVal = CCValid->getZExtValue();
8881 int CCMaskVal = CCMask->getZExtValue();
8888 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
8889 CCMaskVal != CCValidVal)
8890 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
8894 N->getOperand(3), CCReg);
8898SDValue SystemZTargetLowering::combineSELECT_CCMASK(
8899 SDNode *
N, DAGCombinerInfo &DCI)
const {
8905 if (!CCValid || !CCMask)
8908 int CCValidVal = CCValid->getZExtValue();
8909 int CCMaskVal = CCMask->getZExtValue();
8912 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
8916 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
8917 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
8919 if (Val.getOperand(4) != CCReg)
8926 int CCMaskVal = CCMask->getZExtValue();
8927 for (
auto &CC : {0, 1, 2, 3})
8928 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
8942 if (TrueSDVals.empty())
8943 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
8944 if (FalseSDVals.empty())
8945 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
8946 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
8947 SmallSet<SDValue, 4> MergedSDValsSet;
8949 for (
auto CC : {0, 1, 2, 3}) {
8950 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
8951 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
8955 if (MergedSDValsSet.
size() == 1)
8956 return *MergedSDValsSet.
begin();
8957 if (MergedSDValsSet.
size() == 2) {
8958 auto BeginIt = MergedSDValsSet.
begin();
8959 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
8960 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
8963 for (
auto CC : {0, 1, 2, 3}) {
8965 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
8966 ? (TrueSDVals[CC] == NewTrueVal)
8967 : (FalseSDVals[CC] == NewTrueVal);
8969 CCMaskVal = NewCCMask;
8970 CCMaskVal &= CCValidVal;
8973 IsCombinedCCReg =
true;
8981 if (CCMaskVal == CCValidVal)
8984 if (IsCombinedCCReg)
8986 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
8993SDValue SystemZTargetLowering::combineGET_CCMASK(
8994 SDNode *
N, DAGCombinerInfo &DCI)
const {
8999 if (!CCValid || !CCMask)
9001 int CCValidVal = CCValid->getZExtValue();
9002 int CCMaskVal = CCMask->getZExtValue();
9007 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9012 if (!SelectCCValid || !SelectCCMask)
9014 int SelectCCValidVal = SelectCCValid->getZExtValue();
9015 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9019 if (!TrueVal || !FalseVal)
9023 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9024 SelectCCMaskVal ^= SelectCCValidVal;
9028 if (SelectCCValidVal & ~CCValidVal)
9030 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9033 return Select->getOperand(4);
9036SDValue SystemZTargetLowering::combineIntDIVREM(
9037 SDNode *
N, DAGCombinerInfo &DCI)
const {
9038 SelectionDAG &DAG = DCI.DAG;
9039 EVT VT =
N->getValueType(0);
9056SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9057 SDNode *
N, DAGCombinerInfo &DCI)
const {
9058 SelectionDAG &DAG = DCI.DAG;
9062 "SRL or SRA node is required here!");
9064 if (!Subtarget.hasVector())
9074 SDValue ShiftOperand =
N->getOperand(0);
9094 if (!IsSignExt && !IsZeroExt)
9102 unsigned ActiveBits = IsSignExt
9103 ?
Constant->getAPIntValue().getSignificantBits()
9104 :
Constant->getAPIntValue().getActiveBits();
9105 if (ActiveBits > NarrowVTSize)
9121 unsigned ActiveBits = IsSignExt
9122 ?
Constant->getAPIntValue().getSignificantBits()
9123 :
Constant->getAPIntValue().getActiveBits();
9124 if (ActiveBits > NarrowVTSize)
9141 "Cannot have a multiply node with two different operand types.");
9143 "Cannot have an add node with two different operand types.");
9154 if (ShiftAmt != NarrowVTSize)
9158 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9159 NarrowVT == MVT::v4i32 ||
9160 (Subtarget.hasVectorEnhancements3() &&
9161 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9167 MulhRightOp, MulhAddOp);
9168 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9179 EVT VT =
Op.getValueType();
9188 Op =
Op.getOperand(0);
9189 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9193 bool CanUseEven =
true, CanUseOdd =
true;
9194 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9195 if (ShuffleMask[Elt] == -1)
9197 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9199 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9202 Op =
Op.getOperand(0);
9204 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9206 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9212 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9216 Op =
Op.getOperand(0);
9218 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9220 unsigned Elem =
Op.getConstantOperandVal(1);
9221 Op =
Op.getOperand(0);
9223 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9225 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9232SDValue SystemZTargetLowering::combineMUL(
9233 SDNode *
N, DAGCombinerInfo &DCI)
const {
9234 SelectionDAG &DAG = DCI.DAG;
9241 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9242 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9247SDValue SystemZTargetLowering::combineINTRINSIC(
9248 SDNode *
N, DAGCombinerInfo &DCI)
const {
9249 SelectionDAG &DAG = DCI.DAG;
9251 unsigned Id =
N->getConstantOperandVal(1);
9255 case Intrinsic::s390_vll:
9256 case Intrinsic::s390_vlrl:
9258 if (
C->getZExtValue() >= 15)
9259 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9260 N->getOperand(3), MachinePointerInfo());
9263 case Intrinsic::s390_vstl:
9264 case Intrinsic::s390_vstrl:
9266 if (
C->getZExtValue() >= 15)
9267 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9268 N->getOperand(4), MachinePointerInfo());
9276 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9283 switch(
N->getOpcode()) {
9288 case SystemZISD::MERGE_HIGH:
9289 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9294 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9304 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9305 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9308 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9309 case ISD::MUL:
return combineMUL(
N, DCI);
9313 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9325 EVT VT =
Op.getValueType();
9328 unsigned Opcode =
Op.getOpcode();
9330 unsigned Id =
Op.getConstantOperandVal(0);
9332 case Intrinsic::s390_vpksh:
9333 case Intrinsic::s390_vpksf:
9334 case Intrinsic::s390_vpksg:
9335 case Intrinsic::s390_vpkshs:
9336 case Intrinsic::s390_vpksfs:
9337 case Intrinsic::s390_vpksgs:
9338 case Intrinsic::s390_vpklsh:
9339 case Intrinsic::s390_vpklsf:
9340 case Intrinsic::s390_vpklsg:
9341 case Intrinsic::s390_vpklshs:
9342 case Intrinsic::s390_vpklsfs:
9343 case Intrinsic::s390_vpklsgs:
9345 SrcDemE = DemandedElts;
9348 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9351 case Intrinsic::s390_vuphb:
9352 case Intrinsic::s390_vuphh:
9353 case Intrinsic::s390_vuphf:
9354 case Intrinsic::s390_vuplhb:
9355 case Intrinsic::s390_vuplhh:
9356 case Intrinsic::s390_vuplhf:
9357 SrcDemE =
APInt(NumElts * 2, 0);
9360 case Intrinsic::s390_vuplb:
9361 case Intrinsic::s390_vuplhw:
9362 case Intrinsic::s390_vuplf:
9363 case Intrinsic::s390_vupllb:
9364 case Intrinsic::s390_vupllh:
9365 case Intrinsic::s390_vupllf:
9366 SrcDemE =
APInt(NumElts * 2, 0);
9369 case Intrinsic::s390_vpdi: {
9371 SrcDemE =
APInt(NumElts, 0);
9372 if (!DemandedElts[OpNo - 1])
9374 unsigned Mask =
Op.getConstantOperandVal(3);
9375 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9377 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9380 case Intrinsic::s390_vsldb: {
9382 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9383 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9384 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9385 unsigned NumSrc0Els = 16 - FirstIdx;
9386 SrcDemE =
APInt(NumElts, 0);
9388 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9391 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9396 case Intrinsic::s390_vperm:
9405 case SystemZISD::JOIN_DWORDS:
9407 SrcDemE =
APInt(1, 1);
9409 case SystemZISD::SELECT_CCMASK:
9410 SrcDemE = DemandedElts;
9421 const APInt &DemandedElts,
9436 const APInt &DemandedElts,
9438 unsigned Depth)
const {
9442 unsigned Tmp0, Tmp1;
9447 EVT VT =
Op.getValueType();
9448 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9451 "KnownBits does not match VT in bitwidth");
9454 "DemandedElts does not match VT number of elements");
9456 unsigned Opcode =
Op.getOpcode();
9458 bool IsLogical =
false;
9459 unsigned Id =
Op.getConstantOperandVal(0);
9461 case Intrinsic::s390_vpksh:
9462 case Intrinsic::s390_vpksf:
9463 case Intrinsic::s390_vpksg:
9464 case Intrinsic::s390_vpkshs:
9465 case Intrinsic::s390_vpksfs:
9466 case Intrinsic::s390_vpksgs:
9467 case Intrinsic::s390_vpklsh:
9468 case Intrinsic::s390_vpklsf:
9469 case Intrinsic::s390_vpklsg:
9470 case Intrinsic::s390_vpklshs:
9471 case Intrinsic::s390_vpklsfs:
9472 case Intrinsic::s390_vpklsgs:
9473 case Intrinsic::s390_vpdi:
9474 case Intrinsic::s390_vsldb:
9475 case Intrinsic::s390_vperm:
9478 case Intrinsic::s390_vuplhb:
9479 case Intrinsic::s390_vuplhh:
9480 case Intrinsic::s390_vuplhf:
9481 case Intrinsic::s390_vupllb:
9482 case Intrinsic::s390_vupllh:
9483 case Intrinsic::s390_vupllf:
9486 case Intrinsic::s390_vuphb:
9487 case Intrinsic::s390_vuphh:
9488 case Intrinsic::s390_vuphf:
9489 case Intrinsic::s390_vuplb:
9490 case Intrinsic::s390_vuplhw:
9491 case Intrinsic::s390_vuplf: {
9506 case SystemZISD::JOIN_DWORDS:
9507 case SystemZISD::SELECT_CCMASK:
9510 case SystemZISD::REPLICATE: {
9533 if (
LHS == 1)
return 1;
9536 if (
RHS == 1)
return 1;
9537 unsigned Common = std::min(
LHS,
RHS);
9538 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9539 EVT VT =
Op.getValueType();
9541 if (SrcBitWidth > VTBits) {
9542 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9543 if (Common > SrcExtraBits)
9544 return (Common - SrcExtraBits);
9547 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9554 unsigned Depth)
const {
9555 if (
Op.getResNo() != 0)
9557 unsigned Opcode =
Op.getOpcode();
9559 unsigned Id =
Op.getConstantOperandVal(0);
9561 case Intrinsic::s390_vpksh:
9562 case Intrinsic::s390_vpksf:
9563 case Intrinsic::s390_vpksg:
9564 case Intrinsic::s390_vpkshs:
9565 case Intrinsic::s390_vpksfs:
9566 case Intrinsic::s390_vpksgs:
9567 case Intrinsic::s390_vpklsh:
9568 case Intrinsic::s390_vpklsf:
9569 case Intrinsic::s390_vpklsg:
9570 case Intrinsic::s390_vpklshs:
9571 case Intrinsic::s390_vpklsfs:
9572 case Intrinsic::s390_vpklsgs:
9573 case Intrinsic::s390_vpdi:
9574 case Intrinsic::s390_vsldb:
9575 case Intrinsic::s390_vperm:
9577 case Intrinsic::s390_vuphb:
9578 case Intrinsic::s390_vuphh:
9579 case Intrinsic::s390_vuphf:
9580 case Intrinsic::s390_vuplb:
9581 case Intrinsic::s390_vuplhw:
9582 case Intrinsic::s390_vuplf: {
9586 EVT VT =
Op.getValueType();
9596 case SystemZISD::SELECT_CCMASK:
9610 switch (
Op->getOpcode()) {
9611 case SystemZISD::PCREL_WRAPPER:
9612 case SystemZISD::PCREL_OFFSET:
9623 "Unexpected stack alignment");
9626 unsigned StackProbeSize =
9629 StackProbeSize &= ~(StackAlign - 1);
9630 return StackProbeSize ? StackProbeSize : StackAlign;
9647 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9653 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9669 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9671 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9677 if (miI ==
MBB->end()) {
9679 if (Succ->isLiveIn(SystemZ::CC))
9690 switch (
MI.getOpcode()) {
9691 case SystemZ::Select32:
9692 case SystemZ::Select64:
9693 case SystemZ::Select128:
9694 case SystemZ::SelectF32:
9695 case SystemZ::SelectF64:
9696 case SystemZ::SelectF128:
9697 case SystemZ::SelectVR32:
9698 case SystemZ::SelectVR64:
9699 case SystemZ::SelectVR128:
9731 for (
auto *
MI : Selects) {
9732 Register DestReg =
MI->getOperand(0).getReg();
9733 Register TrueReg =
MI->getOperand(1).getReg();
9734 Register FalseReg =
MI->getOperand(2).getReg();
9739 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9742 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9743 TrueReg = It->second.first;
9745 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9746 FalseReg = It->second.second;
9749 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9754 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9765 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9766 assert(TFL->hasReservedCallFrame(MF) &&
9767 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9772 uint32_t NumBytes =
MI.getOperand(0).getImm();
9777 MI.eraseFromParent();
9786 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9788 unsigned CCValid =
MI.getOperand(3).getImm();
9789 unsigned CCMask =
MI.getOperand(4).getImm();
9794 SmallVector<MachineInstr*, 8> Selects;
9795 SmallVector<MachineInstr*, 8> DbgValues;
9801 assert(NextMI.getOperand(3).getImm() == CCValid &&
9802 "Bad CCValid operands since CC was not redefined.");
9803 if (NextMI.getOperand(4).getImm() == CCMask ||
9804 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9810 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9811 NextMI.usesCustomInsertionHook())
9814 for (
auto *SelMI : Selects)
9815 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9819 if (NextMI.isDebugInstr()) {
9821 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9824 }
else if (User || ++
Count > 20)
9828 MachineInstr *LastMI = Selects.back();
9829 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9831 MachineBasicBlock *StartMBB =
MBB;
9861 for (
auto *SelMI : Selects)
9862 SelMI->eraseFromParent();
9865 for (
auto *DbgMI : DbgValues)
9866 MBB->
splice(InsertPos, StartMBB, DbgMI);
9877 unsigned StoreOpcode,
9878 unsigned STOCOpcode,
9879 bool Invert)
const {
9880 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9883 MachineOperand
Base =
MI.getOperand(1);
9884 int64_t Disp =
MI.getOperand(2).getImm();
9885 Register IndexReg =
MI.getOperand(3).getReg();
9886 unsigned CCValid =
MI.getOperand(4).getImm();
9887 unsigned CCMask =
MI.getOperand(5).getImm();
9890 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
9894 MachineMemOperand *MMO =
nullptr;
9895 for (
auto *
I :
MI.memoperands())
9904 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
9916 MI.eraseFromParent();
9924 MachineBasicBlock *StartMBB =
MBB;
9930 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
9957 MI.eraseFromParent();
9967 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9975 MachineBasicBlock *StartMBB =
MBB;
9993 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10012 Register Temp =
MRI.createVirtualRegister(&SystemZ::VR128BitRegClass);
10020 MI.eraseFromParent();
10031 bool Invert)
const {
10033 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10040 int64_t Disp =
MI.getOperand(2).getImm();
10042 Register BitShift =
MI.getOperand(4).getReg();
10043 Register NegBitShift =
MI.getOperand(5).getReg();
10044 unsigned BitSize =
MI.getOperand(6).getImm();
10048 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10049 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10050 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10053 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10054 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10055 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10056 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10057 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10060 MachineBasicBlock *StartMBB =
MBB;
10088 Register Tmp =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10093 }
else if (BinOpcode)
10116 MI.eraseFromParent();
10127 unsigned KeepOldMask)
const {
10129 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10135 int64_t Disp =
MI.getOperand(2).getImm();
10137 Register BitShift =
MI.getOperand(4).getReg();
10138 Register NegBitShift =
MI.getOperand(5).getReg();
10139 unsigned BitSize =
MI.getOperand(6).getImm();
10143 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10144 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10145 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10148 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10149 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10150 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10151 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10152 Register RotatedAltVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10153 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10156 MachineBasicBlock *StartMBB =
MBB;
10220 MI.eraseFromParent();
10230 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10236 int64_t Disp =
MI.getOperand(2).getImm();
10237 Register CmpVal =
MI.getOperand(3).getReg();
10238 Register OrigSwapVal =
MI.getOperand(4).getReg();
10239 Register BitShift =
MI.getOperand(5).getReg();
10240 Register NegBitShift =
MI.getOperand(6).getReg();
10241 int64_t BitSize =
MI.getOperand(7).getImm();
10244 const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
10247 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10248 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10249 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10250 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10253 Register OrigOldVal =
MRI.createVirtualRegister(RC);
10255 Register SwapVal =
MRI.createVirtualRegister(RC);
10256 Register StoreVal =
MRI.createVirtualRegister(RC);
10257 Register OldValRot =
MRI.createVirtualRegister(RC);
10258 Register RetryOldVal =
MRI.createVirtualRegister(RC);
10259 Register RetrySwapVal =
MRI.createVirtualRegister(RC);
10262 MachineBasicBlock *StartMBB =
MBB;
10334 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10337 MI.eraseFromParent();
10345 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10350 .
add(
MI.getOperand(1))
10351 .
addImm(SystemZ::subreg_h64)
10352 .
add(
MI.getOperand(2))
10353 .
addImm(SystemZ::subreg_l64);
10354 MI.eraseFromParent();
10363 bool ClearEven)
const {
10365 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10371 Register In128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10375 Register NewIn128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10376 Register Zero64 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10387 MI.eraseFromParent();
10394 unsigned Opcode,
bool IsMemset)
const {
10396 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10401 uint64_t DestDisp =
MI.getOperand(1).getImm();
10406 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10408 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10409 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10419 SrcDisp =
MI.getOperand(3).getImm();
10421 SrcBase = DestBase;
10422 SrcDisp = DestDisp++;
10423 foldDisplIfNeeded(DestBase, DestDisp);
10426 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10427 bool IsImmForm = LengthMO.
isImm();
10428 bool IsRegForm = !IsImmForm;
10431 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10433 MachineOperand DBase, uint64_t DDisp,
10434 MachineOperand
SBase, uint64_t SDisp,
10435 unsigned Length) ->
void {
10439 if (ByteMO.
isImm())
10454 bool NeedsLoop =
false;
10455 uint64_t ImmLength = 0;
10456 Register LenAdjReg = SystemZ::NoRegister;
10458 ImmLength = LengthMO.
getImm();
10459 ImmLength += IsMemset ? 2 : 1;
10460 if (ImmLength == 0) {
10461 MI.eraseFromParent();
10464 if (Opcode == SystemZ::CLC) {
10465 if (ImmLength > 3 * 256)
10475 }
else if (ImmLength > 6 * 256)
10483 LenAdjReg = LengthMO.
getReg();
10488 MachineBasicBlock *EndMBB =
10489 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10495 MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10497 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10507 auto loadZeroAddress = [&]() -> MachineOperand {
10508 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10512 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10513 DestBase = loadZeroAddress();
10514 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10515 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10517 MachineBasicBlock *StartMBB =
nullptr;
10518 MachineBasicBlock *LoopMBB =
nullptr;
10519 MachineBasicBlock *NextMBB =
nullptr;
10520 MachineBasicBlock *DoneMBB =
nullptr;
10521 MachineBasicBlock *AllDoneMBB =
nullptr;
10525 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10527 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
10528 Register ThisSrcReg =
MRI.createVirtualRegister(RC);
10530 (HaveSingleBase ? ThisSrcReg :
MRI.createVirtualRegister(RC));
10531 Register NextSrcReg =
MRI.createVirtualRegister(RC);
10533 (HaveSingleBase ? NextSrcReg :
MRI.createVirtualRegister(RC));
10534 RC = &SystemZ::GR64BitRegClass;
10535 Register ThisCountReg =
MRI.createVirtualRegister(RC);
10536 Register NextCountReg =
MRI.createVirtualRegister(RC);
10562 MBB = MemsetOneCheckMBB;
10573 MBB = MemsetOneMBB;
10605 if (EndMBB && !ImmLength)
10627 if (!HaveSingleBase)
10634 if (Opcode == SystemZ::MVC)
10661 if (!HaveSingleBase)
10683 Register RemSrcReg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10684 Register RemDestReg = HaveSingleBase ? RemSrcReg
10685 :
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10689 if (!HaveSingleBase)
10697 MachineInstrBuilder EXRL_MIB =
10705 if (Opcode != SystemZ::MVC) {
10715 while (ImmLength > 0) {
10716 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10719 foldDisplIfNeeded(DestBase, DestDisp);
10720 foldDisplIfNeeded(SrcBase, SrcDisp);
10721 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10722 DestDisp += ThisLength;
10723 SrcDisp += ThisLength;
10724 ImmLength -= ThisLength;
10727 if (EndMBB && ImmLength > 0) {
10743 MI.eraseFromParent();
10752 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10756 uint64_t End1Reg =
MI.getOperand(0).getReg();
10757 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10758 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10759 uint64_t CharReg =
MI.getOperand(3).getReg();
10761 const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
10762 uint64_t This1Reg =
MRI.createVirtualRegister(RC);
10763 uint64_t This2Reg =
MRI.createVirtualRegister(RC);
10764 uint64_t End2Reg =
MRI.createVirtualRegister(RC);
10766 MachineBasicBlock *StartMBB =
MBB;
10802 MI.eraseFromParent();
10809 bool NoFloat)
const {
10811 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10812 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10815 MI.setDesc(
TII->get(Opcode));
10819 uint64_t Control =
MI.getOperand(2).getImm();
10820 static const unsigned GPRControlBit[16] = {
10821 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10822 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10824 Control |= GPRControlBit[15];
10825 if (TFI->
hasFP(MF))
10826 Control |= GPRControlBit[11];
10827 MI.getOperand(2).setImm(Control);
10830 for (
int I = 0;
I < 16;
I++) {
10831 if ((Control & GPRControlBit[
I]) == 0) {
10838 if (!NoFloat && (Control & 4) != 0) {
10839 if (Subtarget.hasVector()) {
10857 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10860 Register SrcReg =
MI.getOperand(0).getReg();
10863 const TargetRegisterClass *RC =
MRI->getRegClass(SrcReg);
10864 Register DstReg =
MRI->createVirtualRegister(RC);
10871 MI.eraseFromParent();
10880 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10883 Register DstReg =
MI.getOperand(0).getReg();
10884 Register SizeReg =
MI.getOperand(2).getReg();
10886 MachineBasicBlock *StartMBB =
MBB;
10896 Register PHIReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10897 Register IncReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10962 MI.eraseFromParent();
10966SDValue SystemZTargetLowering::
10969 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
10977 switch (
MI.getOpcode()) {
10978 case SystemZ::ADJCALLSTACKDOWN:
10979 case SystemZ::ADJCALLSTACKUP:
10980 return emitAdjCallStack(
MI,
MBB);
10982 case SystemZ::Select32:
10983 case SystemZ::Select64:
10984 case SystemZ::Select128:
10985 case SystemZ::SelectF32:
10986 case SystemZ::SelectF64:
10987 case SystemZ::SelectF128:
10988 case SystemZ::SelectVR32:
10989 case SystemZ::SelectVR64:
10990 case SystemZ::SelectVR128:
10991 return emitSelect(
MI,
MBB);
10993 case SystemZ::CondStore8Mux:
10994 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
10995 case SystemZ::CondStore8MuxInv:
10996 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
10997 case SystemZ::CondStore16Mux:
10998 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
10999 case SystemZ::CondStore16MuxInv:
11000 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11001 case SystemZ::CondStore32Mux:
11002 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11003 case SystemZ::CondStore32MuxInv:
11004 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11005 case SystemZ::CondStore8:
11006 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11007 case SystemZ::CondStore8Inv:
11008 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11009 case SystemZ::CondStore16:
11010 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11011 case SystemZ::CondStore16Inv:
11012 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11013 case SystemZ::CondStore32:
11014 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11015 case SystemZ::CondStore32Inv:
11016 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11017 case SystemZ::CondStore64:
11018 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11019 case SystemZ::CondStore64Inv:
11020 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11021 case SystemZ::CondStoreF32:
11022 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11023 case SystemZ::CondStoreF32Inv:
11024 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11025 case SystemZ::CondStoreF64:
11026 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11027 case SystemZ::CondStoreF64Inv:
11028 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11030 case SystemZ::SCmp128Hi:
11031 return emitICmp128Hi(
MI,
MBB,
false);
11032 case SystemZ::UCmp128Hi:
11033 return emitICmp128Hi(
MI,
MBB,
true);
11035 case SystemZ::PAIR128:
11036 return emitPair128(
MI,
MBB);
11037 case SystemZ::AEXT128:
11038 return emitExt128(
MI,
MBB,
false);
11039 case SystemZ::ZEXT128:
11040 return emitExt128(
MI,
MBB,
true);
11042 case SystemZ::ATOMIC_SWAPW:
11043 return emitAtomicLoadBinary(
MI,
MBB, 0);
11045 case SystemZ::ATOMIC_LOADW_AR:
11046 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11047 case SystemZ::ATOMIC_LOADW_AFI:
11048 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11050 case SystemZ::ATOMIC_LOADW_SR:
11051 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11053 case SystemZ::ATOMIC_LOADW_NR:
11054 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11055 case SystemZ::ATOMIC_LOADW_NILH:
11056 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11058 case SystemZ::ATOMIC_LOADW_OR:
11059 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11060 case SystemZ::ATOMIC_LOADW_OILH:
11061 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11063 case SystemZ::ATOMIC_LOADW_XR:
11064 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11065 case SystemZ::ATOMIC_LOADW_XILF:
11066 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11068 case SystemZ::ATOMIC_LOADW_NRi:
11069 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11070 case SystemZ::ATOMIC_LOADW_NILHi:
11071 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11073 case SystemZ::ATOMIC_LOADW_MIN:
11075 case SystemZ::ATOMIC_LOADW_MAX:
11077 case SystemZ::ATOMIC_LOADW_UMIN:
11079 case SystemZ::ATOMIC_LOADW_UMAX:
11082 case SystemZ::ATOMIC_CMP_SWAPW:
11083 return emitAtomicCmpSwapW(
MI,
MBB);
11084 case SystemZ::MVCImm:
11085 case SystemZ::MVCReg:
11086 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11087 case SystemZ::NCImm:
11088 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11089 case SystemZ::OCImm:
11090 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11091 case SystemZ::XCImm:
11092 case SystemZ::XCReg:
11093 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11094 case SystemZ::CLCImm:
11095 case SystemZ::CLCReg:
11096 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11097 case SystemZ::MemsetImmImm:
11098 case SystemZ::MemsetImmReg:
11099 case SystemZ::MemsetRegImm:
11100 case SystemZ::MemsetRegReg:
11101 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11102 case SystemZ::CLSTLoop:
11103 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11104 case SystemZ::MVSTLoop:
11105 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11106 case SystemZ::SRSTLoop:
11107 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11108 case SystemZ::TBEGIN:
11109 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11110 case SystemZ::TBEGIN_nofloat:
11111 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11112 case SystemZ::TBEGINC:
11113 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11114 case SystemZ::LTEBRCompare_Pseudo:
11115 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11116 case SystemZ::LTDBRCompare_Pseudo:
11117 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11118 case SystemZ::LTXBRCompare_Pseudo:
11119 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11121 case SystemZ::PROBED_ALLOCA:
11122 return emitProbedAlloca(
MI,
MBB);
11123 case SystemZ::EH_SjLj_SetJmp:
11125 case SystemZ::EH_SjLj_LongJmp:
11128 case TargetOpcode::STACKMAP:
11129 case TargetOpcode::PATCHPOINT:
11140SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11141 if (VT == MVT::Untyped)
11142 return &SystemZ::ADDR128BitRegClass;
11168 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11188 EVT VT =
Op.getValueType();
11189 Op =
Op.getOperand(0);
11190 EVT OpVT =
Op.getValueType();
11192 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11203 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11223 const AttributeList &Attrs =
F->getAttributes();
11224 if (Attrs.hasRetAttrs())
11225 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11226 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11227 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11230 OS << *FT->getParamType(
I);
11232 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11239bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11240 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11241 if (Itr == IsInternalCache.end())
11242 Itr = IsInternalCache
11243 .insert(std::pair<const Function *, bool>(
11246 return Itr->second;
11249void SystemZTargetLowering::
11257 bool IsInternal =
false;
11258 const Function *CalleeFn =
nullptr;
11261 IsInternal = isInternal(CalleeFn);
11262 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11263 errs() <<
"ERROR: Missing extension attribute of passed "
11264 <<
"value in call to function:\n" <<
"Callee: ";
11265 if (CalleeFn !=
nullptr)
11269 errs() <<
"Caller: ";
11275void SystemZTargetLowering::
11283 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11284 errs() <<
"ERROR: Missing extension attribute of returned "
11285 <<
"value from function:\n";
11293bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11295 if (!Subtarget.isTargetELF())
11304 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11305 MVT VT = Outs[i].VT;
11306 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11309 "Unexpected integer argument VT.");
11310 if (VT == MVT::i32 &&
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
static bool isZeroVector(SDValue N)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
Function Alias Analysis Results
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isSelectPseudo(MachineInstr &MI)
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallSet class.
static SDValue getI128Select(SelectionDAG &DAG, const SDLoc &DL, Comparison C, SDValue TrueOp, SDValue FalseOp)
static SmallVector< SDValue, 4 > simplifyAssumingCCVal(SDValue &Val, SDValue &CC, SelectionDAG &DAG)
static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS)
static void adjustForLTGFR(Comparison &C)
static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0, SDValue Op1)
static cl::opt< bool > EnableIntArgExtCheck("argext-abi-check", cl::init(false), cl::desc("Verify that narrow int args are properly extended per the " "SystemZ ABI."))
static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG)
static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT, unsigned Opcode, SDValue Op0, SDValue Op1, SDValue &Even, SDValue &Odd)
static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)
static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Value)
static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In)
static bool isSimpleShift(SDValue N, unsigned &ShiftVal)
static 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 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 std::pair< SDValue, int > findCCUse(const SDValue &Val)
static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static bool isSubBorrowChain(SDValue Carry)
static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool analyzeArgSplit(const SmallVectorImpl< ArgTy > &Args, SmallVector< CCValAssign, 16 > &ArgLocs, unsigned I, MVT &PartVT, unsigned &NumParts)
static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts, unsigned OpNo)
static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op, bool IsNegative)
static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static SDValue expandBitCastI128ToF128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static SDValue tryBuildVectorShuffle(SelectionDAG &DAG, BuildVectorSDNode *BVN)
static SDValue convertFromF16(SDValue Op, SDLoc DL, SelectionDAG &DAG)
static unsigned getVectorComparison(ISD::CondCode CC, CmpMode Mode)
static SDValue lowerGR128ToI128(SelectionDAG &DAG, SDValue In)
static SDValue MergeInputChains(SDNode *N1, SDNode *N2)
static SDValue expandBitCastF128ToI128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, uint64_t Mask, uint64_t CmpVal, unsigned ICmpType)
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL, SDValue Op, SDValue Chain)
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static bool checkCCKill(MachineInstr &MI, MachineBasicBlock *MBB)
static Register forceReg(MachineInstr &MI, MachineOperand &Base, const SystemZInstrInfo *TII)
static bool is32Bit(EVT VT)
static std::pair< unsigned, const TargetRegisterClass * > parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC, const unsigned *Map, unsigned Size)
static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, const SystemZSubtarget &Subtarget, SDValue &Op)
static bool matchDoublePermute(const SmallVectorImpl< int > &Bytes, const Permute &P, SmallVectorImpl< int > &Transform)
static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, SDValue Call, unsigned CCValid, uint64_t CC, ISD::CondCode Cond)
static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg)
static AddressingMode getLoadStoreAddrMode(bool HasVector, Type *Ty)
static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Op0, SDValue Op1)
static void computeKnownBitsBinOp(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static bool getShuffleInput(const SmallVectorImpl< int > &Bytes, unsigned Start, unsigned BytesPerElement, int &Base)
static AddressingMode supportedAddressingMode(Instruction *I, bool HasVector)
static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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.
void setBitsFrom(unsigned loBit)
Set the top bits starting from loBit.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
LLVM Basic Block Representation.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI bool isConstant() const
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
const Constant * getConstVal() const
uint64_t getZExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false, bool IgnoreCastedDirectCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
static auto integer_fixedlen_vector_valuetypes()
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setAdjustsStack(bool V)
void setFrameAddressIsTaken(bool T)
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
reverse_iterator rbegin()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
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.
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.
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.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
LLVM_ABI SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS)
Return an AddrSpaceCastSDNode.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getAtomicLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT MemVT, EVT VT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO)
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI bool isConstantIntBuildVectorOrConstantInt(SDValue N, bool AllowOpaques=true) const
Test whether the given value is a constant int or similar node.
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
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).
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI std::pair< SDValue, SDValue > getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT)
Convert Op, which must be a STRICT operation of float type, to the float type VT, by either extending...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
ArrayRef< int > getMask() const
const_iterator begin() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
StringRef - 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.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A SystemZ-specific class detailing special use registers particular for calling conventions.
virtual int getStackPointerBias()=0
virtual int getReturnFunctionAddressRegister()=0
virtual int getCallFrameSize()=0
virtual int getStackPointerRegister()=0
static SystemZConstantPoolValue * Create(const GlobalValue *GV, SystemZCP::SystemZCPModifier Modifier)
unsigned getVarArgsFrameIndex() const
void setVarArgsFrameIndex(unsigned FI)
void setRegSaveFrameIndex(unsigned FI)
void incNumLocalDynamicTLSAccesses()
Register getVarArgsFirstGPR() const
void setADAVirtualRegister(Register Reg)
void setVarArgsFirstGPR(Register GPR)
Register getADAVirtualRegister() const
void setSizeOfFnParams(unsigned Size)
void setVarArgsFirstFPR(Register FPR)
unsigned getRegSaveFrameIndex() const
Register getVarArgsFirstFPR() const
const SystemZInstrInfo * getInstrInfo() const override
SystemZCallingConventionRegisters * getSpecialRegisters() const
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
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,...
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CondMergingParams getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs) const override
bool useSoftFloat() const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
std::pair< SDValue, SDValue > makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT, ArrayRef< SDValue > Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL, bool DoesNotReturn, bool IsReturnValueUsed) const
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...
SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI)
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, std::optional< CallingConv::ID > CC) const override
Target-specific combining of register parts into its original value.
bool isTruncateFree(Type *, Type *) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg, SDLoc DL, SDValue Chain, bool IsStrict) const
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine the number of bits in the operation that are sign bits.
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool isLegalAddImmediate(int64_t Imm) const override
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
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.
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool PoisonOnly, unsigned Depth) const override
Return true if this function can prove that Op is never poison and, if PoisonOnly is false,...
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
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Let target indicate that an extending atomic load of the specified type is legal.
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...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes) const
Determines the optimal series of memory ops to replace the memset / memcpy.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
unsigned getPointerSize(unsigned AS) const
Get the pointer size for this target.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ 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.
@ 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)
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)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
class_match< Value > 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.
@ Define
Register definition.
@ 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.
FunctionAddr VTableAddr Value
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.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
testing::Matcher< const detail::ErrorHolder & > Failed()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
LLVM_ABI void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
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)
FunctionAddr VTableAddr Count
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.
@ 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...
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.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
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 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 anyextOrTrunc(unsigned BitWidth) const
Return known bits for an "any" extension or truncation of the value we're tracking.
unsigned getBitWidth() const
Get the bit width of this value.
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
void resetAll()
Resets the known state of all bits.
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
KnownBits sext(unsigned BitWidth) const
Return known bits for a sign extension of the value we're tracking.
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.
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.