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}) {
558 for (
auto Op : {ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE})
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();
1262 if (Subtarget.hasInterlockedAccess1() &&
1295 EVT VT =
Y.getValueType();
1298 if (VT == MVT::i32 || VT == MVT::i64)
1299 return Subtarget.hasMiscellaneousExtensions3();
1302 if (VT.
isVector() || VT == MVT::i128)
1303 return Subtarget.hasVector();
1331 bool MVC = Ty->isIntegerTy(8);
1337static AddressingMode
1340 switch (
II->getIntrinsicID()) {
1342 case Intrinsic::memset:
1343 case Intrinsic::memmove:
1344 case Intrinsic::memcpy:
1351 if (SingleUser->getParent() ==
I->getParent()) {
1354 if (
C->getBitWidth() <= 64 &&
1364 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1378 I->getOperand(0)->getType());
1380 bool IsVectorAccess = MemAccessTy->isVectorTy();
1385 Value *DataOp =
I->getOperand(0);
1387 IsVectorAccess =
true;
1393 User *LoadUser = *
I->user_begin();
1395 IsVectorAccess =
true;
1398 if (IsFPAccess || IsVectorAccess)
1417 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1427 return AM.
Scale == 0;
1434 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1435 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1436 const AttributeList &FuncAttributes)
const {
1437 const int MVCFastLen = 16;
1439 if (Limit != ~
unsigned(0)) {
1441 if (
Op.isMemcpy() &&
Op.allowOverlap() &&
Op.size() <= MVCFastLen)
1443 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1445 if (
Op.isZeroMemset())
1450 DstAS, SrcAS, FuncAttributes);
1455 const AttributeList &FuncAttributes)
const {
1456 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1460 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1462 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1464 return FromBits > ToBits;
1472 return FromBits > ToBits;
1481 if (Constraint.
size() == 1) {
1482 switch (Constraint[0]) {
1508 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1509 switch (Constraint[1]) {
1520 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1530 Value *CallOperandVal = Info.CallOperandVal;
1533 if (!CallOperandVal)
1537 switch (*Constraint) {
1556 if (Subtarget.hasVector())
1587 if (
C->getZExtValue() == 0x7fffffff)
1597static std::pair<unsigned, const TargetRegisterClass *>
1599 const unsigned *Map,
unsigned Size) {
1600 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1601 if (isdigit(Constraint[2])) {
1606 return std::make_pair(Map[Index], RC);
1608 return std::make_pair(0U,
nullptr);
1611std::pair<unsigned, const TargetRegisterClass *>
1614 if (Constraint.
size() == 1) {
1616 switch (Constraint[0]) {
1621 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1623 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1624 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1628 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1629 else if (VT == MVT::i128)
1630 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1631 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1634 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1639 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1641 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1643 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1644 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1649 if (Subtarget.hasVector()) {
1651 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1653 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1655 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1656 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1665 auto getVTSizeInBits = [&VT]() {
1673 if (Constraint[1] ==
'r') {
1674 if (getVTSizeInBits() == 32)
1677 if (getVTSizeInBits() == 128)
1683 if (Constraint[1] ==
'f') {
1685 return std::make_pair(
1687 if (getVTSizeInBits() == 16)
1690 if (getVTSizeInBits() == 32)
1693 if (getVTSizeInBits() == 128)
1699 if (Constraint[1] ==
'v') {
1700 if (!Subtarget.hasVector())
1701 return std::make_pair(
1703 if (getVTSizeInBits() == 16)
1706 if (getVTSizeInBits() == 32)
1709 if (getVTSizeInBits() == 64)
1715 if (Constraint[1] ==
'@') {
1716 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1717 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1730 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1731 : SystemZ::NoRegister)
1733 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1740 const Constant *PersonalityFn)
const {
1741 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1745 const Constant *PersonalityFn)
const {
1746 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1761 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1765 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1766 OpInfo.ConstraintVT.getSizeInBits() < 8)
1781 if (Constraint.
size() == 1) {
1782 switch (Constraint[0]) {
1787 Op.getValueType()));
1794 Op.getValueType()));
1801 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1808 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1813 if (
C->getZExtValue() == 0x7fffffff)
1815 Op.getValueType()));
1826#include "SystemZGenCallingConv.inc"
1830 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1836 Type *ToType)
const {
1899 if (BitCastToType == MVT::v2i64)
1926 MVT::Untyped,
Hi,
Lo);
1950 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1952 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1963 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
1964 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1991 unsigned NumFixedGPRs = 0;
1992 unsigned NumFixedFPRs = 0;
1993 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2006 RC = &SystemZ::GR32BitRegClass;
2010 RC = &SystemZ::GR64BitRegClass;
2014 RC = &SystemZ::FP16BitRegClass;
2018 RC = &SystemZ::FP32BitRegClass;
2022 RC = &SystemZ::FP64BitRegClass;
2026 RC = &SystemZ::FP128BitRegClass;
2034 RC = &SystemZ::VR128BitRegClass;
2048 if (Subtarget.isTargetXPLINK64()) {
2051 ArgSPOffset += XPRegs.getCallFrameSize();
2062 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2066 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2077 unsigned ArgIndex = Ins[
I].OrigArgIndex;
2078 assert (Ins[
I].PartOffset == 0);
2079 while (
I + 1 != E && Ins[
I + 1].OrigArgIndex == ArgIndex) {
2081 unsigned PartOffset = Ins[
I + 1].PartOffset;
2092 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2098 Subtarget.getSpecialRegisters());
2104 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2109 if (IsVarArg && Subtarget.isTargetELF()) {
2122 int64_t RegSaveOffset =
2137 &SystemZ::FP64BitRegClass);
2149 if (Subtarget.isTargetXPLINK64()) {
2154 Subtarget.getSpecialRegisters());
2155 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2167 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2174 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2176 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2183 unsigned Offset,
bool LoadAdr =
false) {
2206 bool LoadAddr =
false;
2228 unsigned ADADelta = 0;
2229 unsigned EPADelta = 8;
2235 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2236 G->getGlobal()->hasPrivateLinkage());
2243 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2289 if (Subtarget.isTargetXPLINK64())
2293 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2297 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2316 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2322 unsigned ArgIndex = Outs[
I].OrigArgIndex;
2324 if (
I + 1 != E && Outs[
I + 1].OrigArgIndex == ArgIndex) {
2326 Type *OrigArgType = CLI.
Args[Outs[
I].OrigArgIndex].Ty;
2332 SlotVT = Outs[
I].VT;
2341 assert (Outs[
I].PartOffset == 0);
2342 while (
I + 1 != E && Outs[
I + 1].OrigArgIndex == ArgIndex) {
2343 SDValue PartValue = OutVals[
I + 1];
2344 unsigned PartOffset = Outs[
I + 1].PartOffset;
2351 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2354 ArgValue = SpillSlot;
2371 if (!StackPtr.getNode())
2378 else if (VA.
getLocVT() == MVT::f16)
2391 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2395 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2401 if (!MemOpChains.
empty())
2409 if (Subtarget.isTargetXPLINK64()) {
2414 ->getAddressOfCalleeRegister();
2417 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2424 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2427 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2428 }
else if (IsTailCall) {
2431 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2436 for (
const auto &[Reg,
N] : RegsToPass) {
2443 Ops.push_back(Chain);
2444 Ops.push_back(Callee);
2448 for (
const auto &[Reg,
N] : RegsToPass)
2453 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2454 assert(Mask &&
"Missing call preserved mask for calling convention");
2459 Ops.push_back(Glue);
2468 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2478 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2485 VA.getLocVT(), Glue);
2502 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2504 Args.reserve(
Ops.size());
2510 Entry.IsZExt = !Entry.IsSExt;
2511 Args.push_back(Entry);
2522 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2533 const Type *RetTy)
const {
2536 for (
auto &Out : Outs)
2537 if (Out.ArgVT == MVT::i128)
2541 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2542 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2554 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2562 if (RetLocs.
empty())
2563 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2572 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2594 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2601 unsigned &CCValid) {
2602 unsigned Id =
Op.getConstantOperandVal(1);
2604 case Intrinsic::s390_tbegin:
2605 Opcode = SystemZISD::TBEGIN;
2609 case Intrinsic::s390_tbegin_nofloat:
2610 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2614 case Intrinsic::s390_tend:
2615 Opcode = SystemZISD::TEND;
2628 unsigned Id =
Op.getConstantOperandVal(0);
2630 case Intrinsic::s390_vpkshs:
2631 case Intrinsic::s390_vpksfs:
2632 case Intrinsic::s390_vpksgs:
2633 Opcode = SystemZISD::PACKS_CC;
2637 case Intrinsic::s390_vpklshs:
2638 case Intrinsic::s390_vpklsfs:
2639 case Intrinsic::s390_vpklsgs:
2640 Opcode = SystemZISD::PACKLS_CC;
2644 case Intrinsic::s390_vceqbs:
2645 case Intrinsic::s390_vceqhs:
2646 case Intrinsic::s390_vceqfs:
2647 case Intrinsic::s390_vceqgs:
2648 case Intrinsic::s390_vceqqs:
2649 Opcode = SystemZISD::VICMPES;
2653 case Intrinsic::s390_vchbs:
2654 case Intrinsic::s390_vchhs:
2655 case Intrinsic::s390_vchfs:
2656 case Intrinsic::s390_vchgs:
2657 case Intrinsic::s390_vchqs:
2658 Opcode = SystemZISD::VICMPHS;
2662 case Intrinsic::s390_vchlbs:
2663 case Intrinsic::s390_vchlhs:
2664 case Intrinsic::s390_vchlfs:
2665 case Intrinsic::s390_vchlgs:
2666 case Intrinsic::s390_vchlqs:
2667 Opcode = SystemZISD::VICMPHLS;
2671 case Intrinsic::s390_vtm:
2672 Opcode = SystemZISD::VTM;
2676 case Intrinsic::s390_vfaebs:
2677 case Intrinsic::s390_vfaehs:
2678 case Intrinsic::s390_vfaefs:
2679 Opcode = SystemZISD::VFAE_CC;
2683 case Intrinsic::s390_vfaezbs:
2684 case Intrinsic::s390_vfaezhs:
2685 case Intrinsic::s390_vfaezfs:
2686 Opcode = SystemZISD::VFAEZ_CC;
2690 case Intrinsic::s390_vfeebs:
2691 case Intrinsic::s390_vfeehs:
2692 case Intrinsic::s390_vfeefs:
2693 Opcode = SystemZISD::VFEE_CC;
2697 case Intrinsic::s390_vfeezbs:
2698 case Intrinsic::s390_vfeezhs:
2699 case Intrinsic::s390_vfeezfs:
2700 Opcode = SystemZISD::VFEEZ_CC;
2704 case Intrinsic::s390_vfenebs:
2705 case Intrinsic::s390_vfenehs:
2706 case Intrinsic::s390_vfenefs:
2707 Opcode = SystemZISD::VFENE_CC;
2711 case Intrinsic::s390_vfenezbs:
2712 case Intrinsic::s390_vfenezhs:
2713 case Intrinsic::s390_vfenezfs:
2714 Opcode = SystemZISD::VFENEZ_CC;
2718 case Intrinsic::s390_vistrbs:
2719 case Intrinsic::s390_vistrhs:
2720 case Intrinsic::s390_vistrfs:
2721 Opcode = SystemZISD::VISTR_CC;
2725 case Intrinsic::s390_vstrcbs:
2726 case Intrinsic::s390_vstrchs:
2727 case Intrinsic::s390_vstrcfs:
2728 Opcode = SystemZISD::VSTRC_CC;
2732 case Intrinsic::s390_vstrczbs:
2733 case Intrinsic::s390_vstrczhs:
2734 case Intrinsic::s390_vstrczfs:
2735 Opcode = SystemZISD::VSTRCZ_CC;
2739 case Intrinsic::s390_vstrsb:
2740 case Intrinsic::s390_vstrsh:
2741 case Intrinsic::s390_vstrsf:
2742 Opcode = SystemZISD::VSTRS_CC;
2746 case Intrinsic::s390_vstrszb:
2747 case Intrinsic::s390_vstrszh:
2748 case Intrinsic::s390_vstrszf:
2749 Opcode = SystemZISD::VSTRSZ_CC;
2753 case Intrinsic::s390_vfcedbs:
2754 case Intrinsic::s390_vfcesbs:
2755 Opcode = SystemZISD::VFCMPES;
2759 case Intrinsic::s390_vfchdbs:
2760 case Intrinsic::s390_vfchsbs:
2761 Opcode = SystemZISD::VFCMPHS;
2765 case Intrinsic::s390_vfchedbs:
2766 case Intrinsic::s390_vfchesbs:
2767 Opcode = SystemZISD::VFCMPHES;
2771 case Intrinsic::s390_vftcidb:
2772 case Intrinsic::s390_vftcisb:
2773 Opcode = SystemZISD::VFTCI;
2777 case Intrinsic::s390_tdc:
2778 Opcode = SystemZISD::TDC;
2791 unsigned NumOps =
Op.getNumOperands();
2794 Ops.push_back(
Op.getOperand(0));
2796 Ops.push_back(
Op.getOperand(
I));
2798 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2812 unsigned NumOps =
Op.getNumOperands();
2818 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2819 "Unhandled intrinsic with f16 operand.");
2822 Ops.push_back(CurrOper);
2836 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2837 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2838 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2864 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2867 int64_t
Value = ConstOp1->getSExtValue();
2883 if (!
C.Op0.hasOneUse() ||
2884 C.Op0.getOpcode() != ISD::LOAD ||
2890 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2891 if ((NumBits != 8 && NumBits != 16) ||
2892 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2898 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2901 uint64_t Mask = (1 << NumBits) - 1;
2904 int64_t SignedValue = ConstOp1->getSExtValue();
2911 }
else if (NumBits == 8) {
2937 if (
C.Op0.getValueType() != MVT::i32 ||
2938 Load->getExtensionType() != ExtType) {
2940 Load->getBasePtr(), Load->getPointerInfo(),
2941 Load->getMemoryVT(), Load->getAlign(),
2942 Load->getMemOperand()->getFlags());
2948 if (
C.Op1.getValueType() != MVT::i32 ||
2949 Value != ConstOp1->getZExtValue())
2959 if (Load->getMemoryVT() == MVT::i8)
2962 switch (Load->getExtensionType()) {
2979 if (
C.Op0.getValueType() == MVT::i128)
2981 if (
C.Op0.getValueType() == MVT::f128)
2993 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3022 unsigned Opcode0 =
C.Op0.getOpcode();
3029 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3044 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3045 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3067 if (C1 && C1->isZero()) {
3069 if (
N->getOpcode() == ISD::FNEG) {
3086 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3089 if (C1 && C1->getZExtValue() == 32) {
3090 SDValue ShlOp0 =
C.Op0.getOperand(0);
3109 C.Op0.getOperand(0).getOpcode() == ISD::LOAD &&
3112 C.Op1->getAsZExtVal() == 0) {
3114 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3115 C.Op0.getValueSizeInBits().getFixedValue()) {
3116 unsigned Type = L->getExtensionType();
3119 C.Op0 =
C.Op0.getOperand(0);
3133 uint64_t Amount = Shift->getZExtValue();
3134 if (Amount >=
N.getValueSizeInBits())
3149 unsigned ICmpType) {
3150 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3172 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3178 if (EffectivelyUnsigned && CmpVal <
Low) {
3186 if (CmpVal == Mask) {
3192 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3198 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3206 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3212 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3241 if (
C.Op0.getValueType() == MVT::i128) {
3247 if (Mask && Mask->getAPIntValue() == 0) {
3248 C.Opcode = SystemZISD::VTM;
3249 C.Op1 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8,
C.Op0.getOperand(1));
3250 C.Op0 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8,
C.Op0.getOperand(0));
3265 uint64_t CmpVal = ConstOp1->getZExtValue();
3272 NewC.Op0 =
C.Op0.getOperand(0);
3273 NewC.Op1 =
C.Op0.getOperand(1);
3277 MaskVal = Mask->getZExtValue();
3297 MaskVal = -(CmpVal & -CmpVal);
3306 unsigned NewCCMask, ShiftVal;
3310 (MaskVal >> ShiftVal != 0) &&
3311 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3313 MaskVal >> ShiftVal,
3317 MaskVal >>= ShiftVal;
3321 (MaskVal << ShiftVal != 0) &&
3322 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3324 MaskVal << ShiftVal,
3328 MaskVal <<= ShiftVal;
3337 C.Opcode = SystemZISD::TM;
3339 if (Mask && Mask->getZExtValue() == MaskVal)
3344 C.CCMask = NewCCMask;
3350 if (
C.Opcode != SystemZISD::ICMP)
3352 if (
C.Op0.getValueType() != MVT::i128)
3363 Src = Src.getOperand(0);
3366 unsigned Opcode = 0;
3367 if (Src.hasOneUse()) {
3368 switch (Src.getOpcode()) {
3369 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3370 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3371 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3372 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3373 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3374 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3380 C.Op0 = Src->getOperand(0);
3381 C.Op1 = Src->getOperand(1);
3385 C.CCMask ^=
C.CCValid;
3397 C.Opcode = SystemZISD::VICMPES;
3398 C.Op0 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64,
C.Op0);
3399 C.Op1 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64,
C.Op1);
3409 bool Swap =
false, Invert =
false;
3421 C.Opcode = SystemZISD::UCMP128HI;
3423 C.Opcode = SystemZISD::SCMP128HI;
3428 C.CCMask ^=
C.CCValid;
3439 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3442 if ((~Known.
Zero).getZExtValue() & ~Mask->getZExtValue())
3445 C.Op0 =
C.Op0.getOperand(0);
3457 C.CCValid = CCValid;
3460 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3463 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3467 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3470 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3474 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3477 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3480 C.CCMask &= CCValid;
3488 bool IsSignaling =
false) {
3491 unsigned Opcode, CCValid;
3503 Comparison
C(CmpOp0, CmpOp1, Chain);
3505 if (
C.Op0.getValueType().isFloatingPoint()) {
3508 C.Opcode = SystemZISD::FCMP;
3509 else if (!IsSignaling)
3510 C.Opcode = SystemZISD::STRICT_FCMP;
3512 C.Opcode = SystemZISD::STRICT_FCMPS;
3517 C.Opcode = SystemZISD::ICMP;
3552 if (!
C.Op1.getNode()) {
3554 switch (
C.Op0.getOpcode()) {
3565 if (
C.Opcode == SystemZISD::ICMP)
3566 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3568 if (
C.Opcode == SystemZISD::TM) {
3571 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3574 if (
C.Opcode == SystemZISD::VICMPES ||
3575 C.Opcode == SystemZISD::VICMPHS ||
3576 C.Opcode == SystemZISD::VICMPHLS ||
3577 C.Opcode == SystemZISD::VFCMPES ||
3578 C.Opcode == SystemZISD::VFCMPHS ||
3579 C.Opcode == SystemZISD::VFCMPHES) {
3580 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3587 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3589 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3598 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3599 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3624 unsigned CCValid,
unsigned CCMask) {
3629 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3707 int Mask[] = { Start, -1, Start + 1, -1 };
3711 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3713 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3727 !Subtarget.hasVectorEnhancements1()) {
3733 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3746 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3749 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3750 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3752 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3765 bool IsSignaling)
const {
3768 assert (!IsSignaling || Chain);
3771 bool Invert =
false;
3779 assert(IsFP &&
"Unexpected integer comparison");
3781 DL, VT, CmpOp1, CmpOp0, Chain);
3783 DL, VT, CmpOp0, CmpOp1, Chain);
3787 LT.getValue(1),
GE.getValue(1));
3796 assert(IsFP &&
"Unexpected integer comparison");
3798 DL, VT, CmpOp1, CmpOp0, Chain);
3800 DL, VT, CmpOp0, CmpOp1, Chain);
3804 LT.getValue(1),
GT.getValue(1));
3825 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3829 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3834 Chain =
Cmp.getValue(1);
3842 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3855 EVT VT =
Op.getValueType();
3857 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3866 bool IsSignaling)
const {
3872 EVT VT =
Op.getNode()->getValueType(0);
3874 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3875 Chain, IsSignaling);
3897 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
3931 C.CCMask ^=
C.CCValid;
3939 Op = SystemZISD::VICMPE;
3943 Op = SystemZISD::VICMPHL;
3945 Op = SystemZISD::VICMPH;
3984 C.Op1->getAsZExtVal() == 0) {
3991 if (Subtarget.hasVectorEnhancements3() &&
3992 C.Opcode == SystemZISD::ICMP &&
3993 C.Op0.getValueType() == MVT::i128 &&
4003 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4009 const GlobalValue *GV =
Node->getGlobal();
4015 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4018 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4037 }
else if (Subtarget.isTargetELF()) {
4042 }
else if (Subtarget.isTargetzOS()) {
4073 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4078 Ops.push_back(Chain);
4080 Node->getValueType(0),
4089 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4090 const uint32_t *
Mask =
4092 assert(Mask &&
"Missing call preserved mask for calling convention");
4096 Ops.push_back(Glue);
4099 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4107SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4131 const GlobalValue *GV =
Node->getGlobal();
4139 SDValue TP = lowerThreadPointer(
DL, DAG);
4146 SystemZConstantPoolValue *CPV =
4155 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4161 SystemZConstantPoolValue *CPV =
4170 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4175 SystemZMachineFunctionInfo* MFI =
4204 SystemZConstantPoolValue *CPV =
4238 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4247 if (
CP->isMachineConstantPoolEntry())
4255 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4260 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4262 MachineFrameInfo &MFI = MF.getFrameInfo();
4266 unsigned Depth =
Op.getConstantOperandVal(0);
4273 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4278 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4284 MachinePointerInfo());
4299 unsigned Depth =
Op.getConstantOperandVal(0);
4304 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4307 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4308 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4309 int Offset = TFL->getReturnAddressOffset(MF);
4313 MachinePointerInfo());
4318 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4320 &SystemZ::GR64BitRegClass);
4328 EVT InVT =
In.getValueType();
4329 EVT ResVT =
Op.getValueType();
4337 LoadN->getBasePtr(), LoadN->getMemOperand());
4343 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4345 if (Subtarget.hasHighWord()) {
4349 MVT::i64,
SDValue(U64, 0), In);
4357 DL, MVT::f32, Out64);
4359 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4362 MVT::f64,
SDValue(U64, 0), In);
4364 if (Subtarget.hasHighWord())
4377 if (Subtarget.isTargetXPLINK64())
4378 return lowerVASTART_XPLINK(
Op, DAG);
4380 return lowerVASTART_ELF(
Op, DAG);
4386 SystemZMachineFunctionInfo *FuncInfo =
4387 MF.
getInfo<SystemZMachineFunctionInfo>();
4397 MachinePointerInfo(SV));
4403 SystemZMachineFunctionInfo *FuncInfo =
4404 MF.
getInfo<SystemZMachineFunctionInfo>();
4413 const unsigned NumFields = 4;
4424 for (
unsigned I = 0;
I < NumFields; ++
I) {
4429 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4430 MachinePointerInfo(SV,
Offset));
4448 Align(8),
false,
false,
4449 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4450 MachinePointerInfo(SrcSV));
4454SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4456 if (Subtarget.isTargetXPLINK64())
4457 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4459 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4463SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4465 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4475 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4478 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4479 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4485 if (ExtraAlignSpace)
4489 bool IsSigned =
false;
4490 bool DoesNotReturn =
false;
4491 bool IsReturnValueUsed =
false;
4492 EVT VT =
Op.getValueType();
4502 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4514 if (ExtraAlignSpace) {
4526SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4528 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4531 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4540 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4543 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4544 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4555 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4556 MachinePointerInfo());
4559 if (ExtraAlignSpace)
4566 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4567 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4583 if (RequiredAlign > StackAlign) {
4593 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4594 MachinePointerInfo());
4600SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4604 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4609 unsigned Opcode)
const {
4610 EVT VT =
Op.getValueType();
4616 assert(Subtarget.hasMiscellaneousExtensions2());
4621 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4627 EVT VT =
Op.getValueType();
4635 else if (Subtarget.hasMiscellaneousExtensions2())
4640 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4675 EVT VT =
Op.getValueType();
4688 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4696 EVT VT =
Op.getValueType();
4716 EVT VT =
Op.getValueType();
4723 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4728 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4740 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4742 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4779 MVT::i64, HighOp, Low32);
4785 SDNode *
N =
Op.getNode();
4790 if (
N->getValueType(0) == MVT::i128) {
4791 unsigned BaseOp = 0;
4792 unsigned FlagOp = 0;
4793 bool IsBorrow =
false;
4794 switch (
Op.getOpcode()) {
4798 FlagOp = SystemZISD::VACC;
4802 FlagOp = SystemZISD::VSCBI;
4817 unsigned BaseOp = 0;
4818 unsigned CCValid = 0;
4819 unsigned CCMask = 0;
4821 switch (
Op.getOpcode()) {
4824 BaseOp = SystemZISD::SADDO;
4829 BaseOp = SystemZISD::SSUBO;
4834 BaseOp = SystemZISD::UADDO;
4839 BaseOp = SystemZISD::USUBO;
4845 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4849 if (
N->getValueType(1) == MVT::i1)
4875 SDNode *
N =
Op.getNode();
4876 MVT VT =
N->getSimpleValueType(0);
4887 if (VT == MVT::i128) {
4888 unsigned BaseOp = 0;
4889 unsigned FlagOp = 0;
4890 bool IsBorrow =
false;
4891 switch (
Op.getOpcode()) {
4894 BaseOp = SystemZISD::VAC;
4895 FlagOp = SystemZISD::VACCC;
4898 BaseOp = SystemZISD::VSBI;
4899 FlagOp = SystemZISD::VSBCBI;
4918 unsigned BaseOp = 0;
4919 unsigned CCValid = 0;
4920 unsigned CCMask = 0;
4922 switch (
Op.getOpcode()) {
4928 BaseOp = SystemZISD::ADDCARRY;
4936 BaseOp = SystemZISD::SUBCARRY;
4947 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
4951 if (
N->getValueType(1) == MVT::i1)
4959 EVT VT =
Op.getValueType();
4961 Op =
Op.getOperand(0);
4984 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
4996 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5009 if (NumSignificantBits == 0)
5015 BitSize = std::min(BitSize, OrigBitSize);
5024 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5026 if (BitSize != OrigBitSize)
5058 return DAG.
getNode(ISD::MEMBARRIER,
DL, MVT::Other,
Op.getOperand(0));
5063 EVT RegVT =
Op.getValueType();
5065 return lowerATOMIC_LDST_I128(
Op, DAG);
5066 return lowerLoadF16(
Op, DAG);
5072 if (
Node->getMemoryVT().getSizeInBits() == 128)
5073 return lowerATOMIC_LDST_I128(
Op, DAG);
5074 return lowerStoreF16(
Op, DAG);
5081 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5082 "Only custom lowering i128 or f128.");
5095 EVT WideVT = MVT::i32;
5118 unsigned Opcode)
const {
5122 EVT NarrowVT =
Node->getMemoryVT();
5123 EVT WideVT = MVT::i32;
5124 if (NarrowVT == WideVT)
5131 MachineMemOperand *MMO =
Node->getMemOperand();
5135 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5137 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5142 SDValue AlignedAddr, BitShift, NegBitShift;
5150 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5153 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5154 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5159 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5160 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5180 EVT MemVT =
Node->getMemoryVT();
5181 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5183 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5184 assert(Subtarget.hasInterlockedAccess1() &&
5185 "Should have been expanded by AtomicExpand pass.");
5190 return DAG.
getAtomic(ISD::ATOMIC_LOAD_ADD,
DL, MemVT,
5191 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5192 Node->getMemOperand());
5195 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5206 MachineMemOperand *MMO =
Node->getMemOperand();
5209 if (
Node->getMemoryVT() == MVT::i128) {
5218 EVT NarrowVT =
Node->getMemoryVT();
5219 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5220 if (NarrowVT == WideVT) {
5221 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5222 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5224 DL, Tys,
Ops, NarrowVT, MMO);
5238 SDValue AlignedAddr, BitShift, NegBitShift;
5242 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5243 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5246 VTList,
Ops, NarrowVT, MMO);
5260SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5283 auto *Regs = Subtarget.getSpecialRegisters();
5286 "in GHC calling convention");
5288 Regs->getStackPointerRegister(),
Op.getValueType());
5294 auto *Regs = Subtarget.getSpecialRegisters();
5295 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5299 "in GHC calling convention");
5306 if (StoreBackchain) {
5308 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5309 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5310 MachinePointerInfo());
5313 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5316 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5317 MachinePointerInfo());
5324 bool IsData =
Op.getConstantOperandVal(4);
5327 return Op.getOperand(0);
5330 bool IsWrite =
Op.getConstantOperandVal(2);
5337 Node->getMemoryVT(),
Node->getMemOperand());
5341SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5343 unsigned Opcode, CCValid;
5345 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5356SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5358 unsigned Opcode, CCValid;
5361 if (
Op->getNumValues() == 1)
5363 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5368 unsigned Id =
Op.getConstantOperandVal(0);
5370 case Intrinsic::thread_pointer:
5371 return lowerThreadPointer(SDLoc(
Op), DAG);
5373 case Intrinsic::s390_vpdi:
5374 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5375 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5377 case Intrinsic::s390_vperm:
5378 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5379 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5381 case Intrinsic::s390_vuphb:
5382 case Intrinsic::s390_vuphh:
5383 case Intrinsic::s390_vuphf:
5384 case Intrinsic::s390_vuphg:
5385 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5388 case Intrinsic::s390_vuplhb:
5389 case Intrinsic::s390_vuplhh:
5390 case Intrinsic::s390_vuplhf:
5391 case Intrinsic::s390_vuplhg:
5392 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5395 case Intrinsic::s390_vuplb:
5396 case Intrinsic::s390_vuplhw:
5397 case Intrinsic::s390_vuplf:
5398 case Intrinsic::s390_vuplg:
5399 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5402 case Intrinsic::s390_vupllb:
5403 case Intrinsic::s390_vupllh:
5404 case Intrinsic::s390_vupllf:
5405 case Intrinsic::s390_vupllg:
5406 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5409 case Intrinsic::s390_vsumb:
5410 case Intrinsic::s390_vsumh:
5411 case Intrinsic::s390_vsumgh:
5412 case Intrinsic::s390_vsumgf:
5413 case Intrinsic::s390_vsumqf:
5414 case Intrinsic::s390_vsumqg:
5415 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5416 Op.getOperand(1),
Op.getOperand(2));
5418 case Intrinsic::s390_vaq:
5420 Op.getOperand(1),
Op.getOperand(2));
5421 case Intrinsic::s390_vaccb:
5422 case Intrinsic::s390_vacch:
5423 case Intrinsic::s390_vaccf:
5424 case Intrinsic::s390_vaccg:
5425 case Intrinsic::s390_vaccq:
5426 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5427 Op.getOperand(1),
Op.getOperand(2));
5428 case Intrinsic::s390_vacq:
5429 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5430 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5431 case Intrinsic::s390_vacccq:
5432 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5433 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5435 case Intrinsic::s390_vsq:
5437 Op.getOperand(1),
Op.getOperand(2));
5438 case Intrinsic::s390_vscbib:
5439 case Intrinsic::s390_vscbih:
5440 case Intrinsic::s390_vscbif:
5441 case Intrinsic::s390_vscbig:
5442 case Intrinsic::s390_vscbiq:
5443 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5444 Op.getOperand(1),
Op.getOperand(2));
5445 case Intrinsic::s390_vsbiq:
5446 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5447 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5448 case Intrinsic::s390_vsbcbiq:
5449 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5450 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5452 case Intrinsic::s390_vmhb:
5453 case Intrinsic::s390_vmhh:
5454 case Intrinsic::s390_vmhf:
5455 case Intrinsic::s390_vmhg:
5456 case Intrinsic::s390_vmhq:
5458 Op.getOperand(1),
Op.getOperand(2));
5459 case Intrinsic::s390_vmlhb:
5460 case Intrinsic::s390_vmlhh:
5461 case Intrinsic::s390_vmlhf:
5462 case Intrinsic::s390_vmlhg:
5463 case Intrinsic::s390_vmlhq:
5465 Op.getOperand(1),
Op.getOperand(2));
5467 case Intrinsic::s390_vmahb:
5468 case Intrinsic::s390_vmahh:
5469 case Intrinsic::s390_vmahf:
5470 case Intrinsic::s390_vmahg:
5471 case Intrinsic::s390_vmahq:
5472 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5473 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5474 case Intrinsic::s390_vmalhb:
5475 case Intrinsic::s390_vmalhh:
5476 case Intrinsic::s390_vmalhf:
5477 case Intrinsic::s390_vmalhg:
5478 case Intrinsic::s390_vmalhq:
5479 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5480 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5482 case Intrinsic::s390_vmeb:
5483 case Intrinsic::s390_vmeh:
5484 case Intrinsic::s390_vmef:
5485 case Intrinsic::s390_vmeg:
5486 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5487 Op.getOperand(1),
Op.getOperand(2));
5488 case Intrinsic::s390_vmleb:
5489 case Intrinsic::s390_vmleh:
5490 case Intrinsic::s390_vmlef:
5491 case Intrinsic::s390_vmleg:
5492 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5493 Op.getOperand(1),
Op.getOperand(2));
5494 case Intrinsic::s390_vmob:
5495 case Intrinsic::s390_vmoh:
5496 case Intrinsic::s390_vmof:
5497 case Intrinsic::s390_vmog:
5498 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5499 Op.getOperand(1),
Op.getOperand(2));
5500 case Intrinsic::s390_vmlob:
5501 case Intrinsic::s390_vmloh:
5502 case Intrinsic::s390_vmlof:
5503 case Intrinsic::s390_vmlog:
5504 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5505 Op.getOperand(1),
Op.getOperand(2));
5507 case Intrinsic::s390_vmaeb:
5508 case Intrinsic::s390_vmaeh:
5509 case Intrinsic::s390_vmaef:
5510 case Intrinsic::s390_vmaeg:
5512 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5513 Op.getOperand(1),
Op.getOperand(2)),
5515 case Intrinsic::s390_vmaleb:
5516 case Intrinsic::s390_vmaleh:
5517 case Intrinsic::s390_vmalef:
5518 case Intrinsic::s390_vmaleg:
5520 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5521 Op.getOperand(1),
Op.getOperand(2)),
5523 case Intrinsic::s390_vmaob:
5524 case Intrinsic::s390_vmaoh:
5525 case Intrinsic::s390_vmaof:
5526 case Intrinsic::s390_vmaog:
5528 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5529 Op.getOperand(1),
Op.getOperand(2)),
5531 case Intrinsic::s390_vmalob:
5532 case Intrinsic::s390_vmaloh:
5533 case Intrinsic::s390_vmalof:
5534 case Intrinsic::s390_vmalog:
5536 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5537 Op.getOperand(1),
Op.getOperand(2)),
5558 { SystemZISD::MERGE_HIGH, 8,
5559 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5561 { SystemZISD::MERGE_HIGH, 4,
5562 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5564 { SystemZISD::MERGE_HIGH, 2,
5565 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5567 { SystemZISD::MERGE_HIGH, 1,
5568 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5570 { SystemZISD::MERGE_LOW, 8,
5571 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5573 { SystemZISD::MERGE_LOW, 4,
5574 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5576 { SystemZISD::MERGE_LOW, 2,
5577 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5579 { SystemZISD::MERGE_LOW, 1,
5580 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5582 { SystemZISD::PACK, 4,
5583 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5585 { SystemZISD::PACK, 2,
5586 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5588 { SystemZISD::PACK, 1,
5589 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5591 { SystemZISD::PERMUTE_DWORDS, 4,
5592 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5594 { SystemZISD::PERMUTE_DWORDS, 1,
5595 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5609 OpNo0 = OpNo1 = OpNos[1];
5610 }
else if (OpNos[1] < 0) {
5611 OpNo0 = OpNo1 = OpNos[0];
5629 unsigned &OpNo0,
unsigned &OpNo1) {
5630 int OpNos[] = { -1, -1 };
5643 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5645 OpNos[ModelOpNo] = RealOpNo;
5653 unsigned &OpNo0,
unsigned &OpNo1) {
5670 int Elt = Bytes[From];
5673 Transform[From] = -1;
5675 while (
P.Bytes[To] != Elt) {
5680 Transform[From] = To;
5704 Bytes.
resize(NumElements * BytesPerElement, -1);
5705 for (
unsigned I = 0;
I < NumElements; ++
I) {
5706 int Index = VSN->getMaskElt(
I);
5708 for (
unsigned J = 0; J < BytesPerElement; ++J)
5709 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5713 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5716 Bytes.
resize(NumElements * BytesPerElement, -1);
5717 for (
unsigned I = 0;
I < NumElements; ++
I)
5718 for (
unsigned J = 0; J < BytesPerElement; ++J)
5719 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5730 unsigned BytesPerElement,
int &
Base) {
5732 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5733 if (Bytes[Start +
I] >= 0) {
5734 unsigned Elem = Bytes[Start +
I];
5738 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5740 }
else if (
unsigned(
Base) != Elem -
I)
5753 unsigned &StartIndex,
unsigned &OpNo0,
5755 int OpNos[] = { -1, -1 };
5757 for (
unsigned I = 0;
I < 16; ++
I) {
5758 int Index = Bytes[
I];
5764 Shift = ExpectedShift;
5765 else if (Shift != ExpectedShift)
5769 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5771 OpNos[ModelOpNo] = RealOpNo;
5784 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5785 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5790 Op0 = DAG.
getNode(ISD::BITCAST,
DL, InVT, Op0);
5791 Op1 = DAG.
getNode(ISD::BITCAST,
DL, InVT, Op1);
5793 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5795 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5796 }
else if (
P.Opcode == SystemZISD::PACK) {
5799 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5807 if (
N->getOpcode() == ISD::BITCAST)
5808 N =
N->getOperand(0);
5811 return Op->getZExtValue() == 0;
5817 for (
unsigned I = 0;
I < Num ;
I++)
5829 for (
unsigned I = 0;
I < 2; ++
I)
5833 unsigned StartIndex, OpNo0, OpNo1;
5835 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5842 if (ZeroVecIdx != UINT32_MAX) {
5843 bool MaskFirst =
true;
5848 if (OpNo == ZeroVecIdx &&
I == 0) {
5853 if (OpNo != ZeroVecIdx && Byte == 0) {
5860 if (ZeroIdx != -1) {
5863 if (Bytes[
I] >= 0) {
5866 if (OpNo == ZeroVecIdx)
5878 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5881 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5893 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5899struct GeneralShuffle {
5900 GeneralShuffle(EVT vt)
5901 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
5905 void tryPrepareForUnpack();
5906 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
5921 unsigned UnpackFromEltSize;
5928void GeneralShuffle::addUndef() {
5930 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5931 Bytes.push_back(-1);
5940bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
5946 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
5951 if (FromBytesPerElement < BytesPerElement)
5955 (FromBytesPerElement - BytesPerElement));
5958 while (
Op.getNode()) {
5959 if (
Op.getOpcode() == ISD::BITCAST)
5960 Op =
Op.getOperand(0);
5976 }
else if (
Op.isUndef()) {
5985 for (; OpNo <
Ops.size(); ++OpNo)
5986 if (
Ops[OpNo] ==
Op)
5988 if (OpNo ==
Ops.size())
5993 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5994 Bytes.push_back(
Base +
I);
6003 if (
Ops.size() == 0)
6007 tryPrepareForUnpack();
6010 if (
Ops.size() == 1)
6022 unsigned Stride = 1;
6023 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6024 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6034 else if (OpNo ==
I + Stride)
6045 if (NewBytes[J] >= 0) {
6047 "Invalid double permute");
6050 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6056 if (NewBytes[J] >= 0)
6072 unsigned OpNo0, OpNo1;
6076 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6081 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6088 dbgs() << Msg.c_str() <<
" { ";
6089 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6090 dbgs() << Bytes[
I] <<
" ";
6098void GeneralShuffle::tryPrepareForUnpack() {
6100 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6105 if (
Ops.size() > 2 &&
6110 UnpackFromEltSize = 1;
6111 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6112 bool MatchUnpack =
true;
6115 unsigned ToEltSize = UnpackFromEltSize * 2;
6116 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6119 if (Bytes[Elt] != -1) {
6121 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6122 MatchUnpack =
false;
6128 if (
Ops.size() == 2) {
6130 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6132 if (SrcBytes[i] == -1)
6134 if (SrcBytes[i] % 16 !=
int(i))
6135 CanUseUnpackHigh =
false;
6137 CanUseUnpackLow =
false;
6138 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6139 UnpackFromEltSize = UINT_MAX;
6143 if (!CanUseUnpackHigh)
6149 if (UnpackFromEltSize > 4)
6152 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6153 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6155 dumpBytes(Bytes,
"Original Bytes vector:"););
6164 Elt += UnpackFromEltSize;
6165 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6166 Bytes[
B] = Bytes[Elt];
6174 Ops.erase(&
Ops[ZeroVecOpNo]);
6176 if (Bytes[
I] >= 0) {
6178 if (OpNo > ZeroVecOpNo)
6189 if (!unpackWasPrepared())
6191 unsigned InBits = UnpackFromEltSize * 8;
6195 unsigned OutBits = InBits * 2;
6198 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6199 : SystemZISD::UNPACKL_HIGH,
6200 DL, OutVT, PackedOp);
6205 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6206 if (!
Op.getOperand(
I).isUndef())
6222 if (
Value.isUndef())
6234 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6237 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6238 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6259 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6275 GeneralShuffle GS(VT);
6277 bool FoundOne =
false;
6278 for (
unsigned I = 0;
I < NumElements; ++
I) {
6281 Op =
Op.getOperand(0);
6284 unsigned Elem =
Op.getConstantOperandVal(1);
6285 if (!GS.add(
Op.getOperand(0), Elem))
6288 }
else if (
Op.isUndef()) {
6302 if (!ResidueOps.
empty()) {
6303 while (ResidueOps.
size() < NumElements)
6305 for (
auto &
Op : GS.Ops) {
6306 if (!
Op.getNode()) {
6312 return GS.getNode(DAG,
SDLoc(BVN));
6315bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6319 if (
AL->getOpcode() == ISD::ATOMIC_LOAD)
6321 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6332 unsigned int NumElements = Elems.
size();
6333 unsigned int Count = 0;
6334 for (
auto Elem : Elems) {
6335 if (!Elem.isUndef()) {
6338 else if (Elem != Single) {
6358 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6359 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6362 bool AllLoads =
true;
6363 for (
auto Elem : Elems)
6364 if (!isVectorElementLoad(Elem)) {
6370 if (VT == MVT::v2i64 && !AllLoads)
6374 if (VT == MVT::v2f64 && !AllLoads)
6384 if (VT == MVT::v4f32 && !AllLoads) {
6393 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6395 Op01 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64, Op01);
6396 Op23 = DAG.
getNode(ISD::BITCAST,
DL, MVT::v2i64, Op23);
6398 DL, MVT::v2i64, Op01, Op23);
6406 unsigned NumConstants = 0;
6407 for (
unsigned I = 0;
I < NumElements; ++
I) {
6421 if (NumConstants > 0) {
6422 for (
unsigned I = 0;
I < NumElements; ++
I)
6433 std::map<const SDNode*, unsigned> UseCounts;
6434 SDNode *LoadMaxUses =
nullptr;
6435 for (
unsigned I = 0;
I < NumElements; ++
I)
6436 if (isVectorElementLoad(Elems[
I])) {
6437 SDNode *Ld = Elems[
I].getNode();
6438 unsigned Count = ++UseCounts[Ld];
6439 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6442 if (LoadMaxUses !=
nullptr) {
6443 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6447 unsigned I1 = NumElements / 2 - 1;
6448 unsigned I2 = NumElements - 1;
6449 bool Def1 = !Elems[
I1].isUndef();
6450 bool Def2 = !Elems[I2].isUndef();
6464 for (
unsigned I = 0;
I < NumElements; ++
I)
6465 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6475 EVT VT =
Op.getValueType();
6477 if (BVN->isConstant()) {
6478 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6496 for (
unsigned I = 0;
I < NumElements; ++
I)
6498 return buildVector(DAG,
DL, VT,
Ops);
6505 EVT VT =
Op.getValueType();
6508 if (VSN->isSplat()) {
6510 unsigned Index = VSN->getSplatIndex();
6512 "Splat index should be defined and in first operand");
6518 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6522 GeneralShuffle
GS(VT);
6523 for (
unsigned I = 0;
I < NumElements; ++
I) {
6524 int Elt = VSN->getMaskElt(
I);
6527 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6528 unsigned(Elt) % NumElements))
6531 return GS.getNode(DAG, SDLoc(VSN));
6550 EVT VT =
Op.getValueType();
6555 if (VT == MVT::v2f64 &&
6569 DAG.
getNode(ISD::BITCAST,
DL, IntVecVT, Op0),
6570 DAG.
getNode(ISD::BITCAST,
DL, IntVT, Op1), Op2);
6571 return DAG.
getNode(ISD::BITCAST,
DL, VT, Res);
6575SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6581 EVT VT =
Op.getValueType();
6586 uint64_t
Index = CIndexN->getZExtValue();
6596 DAG.
getNode(ISD::BITCAST,
DL, IntVecVT, Op0), Op1);
6597 return DAG.
getNode(ISD::BITCAST,
DL, VT, Res);
6600SDValue SystemZTargetLowering::
6603 EVT OutVT =
Op.getValueType();
6607 unsigned StartOffset = 0;
6614 ArrayRef<int> ShuffleMask = SVN->
getMask();
6619 if (ToBits == 64 && OutNumElts == 2) {
6620 int NumElem = ToBits / FromBits;
6621 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6627 int StartOffsetCandidate = -1;
6628 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6629 if (ShuffleMask[Elt] == -1)
6631 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6632 if (StartOffsetCandidate == -1)
6633 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6634 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6637 StartOffsetCandidate = -1;
6640 if (StartOffsetCandidate != -1) {
6641 StartOffset = StartOffsetCandidate;
6650 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6651 if (StartOffset >= OutNumElts) {
6652 Opcode = SystemZISD::UNPACK_LOW;
6653 StartOffset -= OutNumElts;
6655 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6656 }
while (FromBits != ToBits);
6661SDValue SystemZTargetLowering::
6665 EVT OutVT =
Op.getValueType();
6669 unsigned NumInPerOut = InNumElts / OutNumElts;
6674 SmallVector<int, 16>
Mask(InNumElts);
6675 unsigned ZeroVecElt = InNumElts;
6676 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6677 unsigned MaskElt = PackedElt * NumInPerOut;
6678 unsigned End = MaskElt + NumInPerOut - 1;
6679 for (; MaskElt < End; MaskElt++)
6680 Mask[MaskElt] = ZeroVecElt++;
6681 Mask[MaskElt] = PackedElt;
6684 return DAG.
getNode(ISD::BITCAST,
DL, OutVT, Shuf);
6688 unsigned ByScalar)
const {
6693 EVT VT =
Op.getValueType();
6698 APInt SplatBits, SplatUndef;
6699 unsigned SplatBitSize;
6703 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6704 ElemBitSize,
true) &&
6705 SplatBitSize == ElemBitSize) {
6708 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6711 BitVector UndefElements;
6717 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6724 if (VSN->isSplat()) {
6725 SDValue VSNOp0 = VSN->getOperand(0);
6726 unsigned Index = VSN->getSplatIndex();
6728 "Splat index should be defined and in first operand");
6735 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6753 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6754 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6757 if (ShiftAmt > 120) {
6761 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6765 SmallVector<int, 16>
Mask(16);
6766 for (
unsigned Elt = 0; Elt < 16; Elt++)
6767 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6769 if ((ShiftAmt & 7) == 0)
6773 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6791 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6792 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6795 if (ShiftAmt > 120) {
6799 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6803 SmallVector<int, 16>
Mask(16);
6804 for (
unsigned Elt = 0; Elt < 16; Elt++)
6805 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6807 if ((ShiftAmt & 7) == 0)
6811 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6823 MVT DstVT =
Op.getSimpleValueType();
6826 unsigned SrcAS =
N->getSrcAddressSpace();
6828 assert(SrcAS !=
N->getDestAddressSpace() &&
6829 "addrspacecast must be between different address spaces");
6837 }
else if (DstVT == MVT::i32) {
6851 if (
In.getSimpleValueType() != MVT::f16)
6858 SDValue Chain,
bool IsStrict)
const {
6859 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
6862 std::tie(Result, Chain) =
6871 bool IsStrict =
Op->isStrictFPOpcode();
6873 MVT VT =
Op.getSimpleValueType();
6874 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6882 if (!Subtarget.hasFPExtension() && !IsSigned)
6893 if (VT == MVT::i128) {
6896 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6906 bool IsStrict =
Op->isStrictFPOpcode();
6908 MVT VT =
Op.getSimpleValueType();
6909 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6914 if (VT == MVT::f16) {
6921 if (!Subtarget.hasFPExtension() && !IsSigned)
6924 if (InVT == MVT::i128) {
6927 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6936 assert(
Op.getSimpleValueType() == MVT::i64 &&
6937 "Expexted to convert i64 to f16.");
6949 assert(
Op.getSimpleValueType() == MVT::f16 &&
6950 "Expected to convert f16 to i64.");
6963 EVT RegVT =
Op.getValueType();
6964 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
6971 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
6973 AtomicLd->getChain(), AtomicLd->getBasePtr(),
6974 AtomicLd->getMemOperand());
6993 return DAG.
getAtomic(ISD::ATOMIC_STORE,
DL, MVT::i16, AtomicSt->getChain(),
6994 Shft, AtomicSt->getBasePtr(),
6995 AtomicSt->getMemOperand());
7005 MVT ResultVT =
Op.getSimpleValueType();
7007 unsigned Check =
Op.getConstantOperandVal(1);
7009 unsigned TDCMask = 0;
7046 MachinePointerInfo MPI =
7052 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7056 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7061 switch (
Op.getOpcode()) {
7063 return lowerFRAMEADDR(
Op, DAG);
7065 return lowerRETURNADDR(
Op, DAG);
7067 return lowerBR_CC(
Op, DAG);
7069 return lowerSELECT_CC(
Op, DAG);
7071 return lowerSETCC(
Op, DAG);
7073 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7075 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7087 return lowerBITCAST(
Op, DAG);
7089 return lowerVASTART(
Op, DAG);
7091 return lowerVACOPY(
Op, DAG);
7092 case ISD::DYNAMIC_STACKALLOC:
7093 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7094 case ISD::GET_DYNAMIC_AREA_OFFSET:
7095 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7097 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7099 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7101 return lowerSMUL_LOHI(
Op, DAG);
7103 return lowerUMUL_LOHI(
Op, DAG);
7105 return lowerSDIVREM(
Op, DAG);
7107 return lowerUDIVREM(
Op, DAG);
7112 return lowerXALUO(
Op, DAG);
7115 return lowerUADDSUBO_CARRY(
Op, DAG);
7117 return lowerOR(
Op, DAG);
7119 return lowerCTPOP(
Op, DAG);
7120 case ISD::VECREDUCE_ADD:
7121 return lowerVECREDUCE_ADD(
Op, DAG);
7122 case ISD::ATOMIC_FENCE:
7123 return lowerATOMIC_FENCE(
Op, DAG);
7124 case ISD::ATOMIC_SWAP:
7125 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7126 case ISD::ATOMIC_STORE:
7127 return lowerATOMIC_STORE(
Op, DAG);
7128 case ISD::ATOMIC_LOAD:
7129 return lowerATOMIC_LOAD(
Op, DAG);
7130 case ISD::ATOMIC_LOAD_ADD:
7131 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7132 case ISD::ATOMIC_LOAD_SUB:
7133 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7134 case ISD::ATOMIC_LOAD_AND:
7135 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7136 case ISD::ATOMIC_LOAD_OR:
7137 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7138 case ISD::ATOMIC_LOAD_XOR:
7139 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7140 case ISD::ATOMIC_LOAD_NAND:
7141 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7142 case ISD::ATOMIC_LOAD_MIN:
7143 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7144 case ISD::ATOMIC_LOAD_MAX:
7145 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7146 case ISD::ATOMIC_LOAD_UMIN:
7147 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7148 case ISD::ATOMIC_LOAD_UMAX:
7149 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7150 case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
7151 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7152 case ISD::STACKSAVE:
7153 return lowerSTACKSAVE(
Op, DAG);
7154 case ISD::STACKRESTORE:
7155 return lowerSTACKRESTORE(
Op, DAG);
7157 return lowerPREFETCH(
Op, DAG);
7159 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7161 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7163 return lowerBUILD_VECTOR(
Op, DAG);
7165 return lowerVECTOR_SHUFFLE(
Op, DAG);
7167 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7169 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7171 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7173 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7175 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7177 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7179 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7181 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7182 case ISD::ADDRSPACECAST:
7185 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7187 return lowerFSHL(
Op, DAG);
7189 return lowerFSHR(
Op, DAG);
7190 case ISD::FP_EXTEND:
7192 return lowerFP_EXTEND(
Op, DAG);
7197 return lower_FP_TO_INT(
Op, DAG);
7202 return lower_INT_TO_FP(
Op, DAG);
7204 return lowerLoadF16(
Op, DAG);
7206 return lowerStoreF16(
Op, DAG);
7208 return lowerIS_FPCLASS(
Op, DAG);
7210 return lowerGET_ROUNDING(
Op, DAG);
7211 case ISD::READCYCLECOUNTER:
7212 return lowerREADCYCLECOUNTER(
Op, DAG);
7234 &SystemZ::FP128BitRegClass);
7243 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7258 &SystemZ::FP128BitRegClass);
7275 switch (
N->getOpcode()) {
7276 case ISD::ATOMIC_LOAD: {
7279 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7282 DL, Tys,
Ops, MVT::i128, MMO);
7285 if (
N->getValueType(0) == MVT::f128)
7291 case ISD::ATOMIC_STORE: {
7299 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7302 DL, Tys,
Ops, MVT::i128, MMO);
7308 MVT::Other, Res), 0);
7312 case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS: {
7320 DL, Tys,
Ops, MVT::i128, MMO);
7329 case ISD::BITCAST: {
7334 EVT SrcVT = Src.getValueType();
7335 EVT ResVT =
N->getValueType(0);
7336 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7338 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7339 if (Subtarget.hasVector()) {
7347 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7349 Subtarget.hasVector()
7363 bool IsStrict =
N->isStrictFPOpcode();
7365 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7366 EVT ResVT =
N->getValueType(0);
7368 if (ResVT == MVT::f16) {
7391 bool IsStrict =
N->isStrictFPOpcode();
7393 EVT ResVT =
N->getValueType(0);
7394 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7397 if (InVT == MVT::f16) {
7403 std::tie(InF32, Chain) =
7428bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7429 if (!Subtarget.hasVector())
7443 DAGCombinerInfo &DCI,
7451 unsigned Opcode =
Op.getOpcode();
7452 if (Opcode == ISD::BITCAST)
7454 Op =
Op.getOperand(0);
7456 canTreatAsByteVector(
Op.getValueType())) {
7465 BytesPerElement,
First))
7472 if (Byte % BytesPerElement != 0)
7475 Index = Byte / BytesPerElement;
7479 canTreatAsByteVector(
Op.getValueType())) {
7482 EVT OpVT =
Op.getValueType();
7484 if (OpBytesPerElement < BytesPerElement)
7488 unsigned End = (
Index + 1) * BytesPerElement;
7489 if (End % OpBytesPerElement != 0)
7492 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7493 if (!
Op.getValueType().isInteger()) {
7496 DCI.AddToWorklist(
Op.getNode());
7501 DCI.AddToWorklist(
Op.getNode());
7508 canTreatAsByteVector(
Op.getValueType()) &&
7509 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7511 EVT ExtVT =
Op.getValueType();
7512 EVT OpVT =
Op.getOperand(0).getValueType();
7515 unsigned Byte =
Index * BytesPerElement;
7516 unsigned SubByte =
Byte % ExtBytesPerElement;
7517 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7518 if (SubByte < MinSubByte ||
7519 SubByte + BytesPerElement > ExtBytesPerElement)
7522 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7524 Byte += SubByte - MinSubByte;
7525 if (Byte % BytesPerElement != 0)
7527 Op =
Op.getOperand(0);
7534 if (
Op.getValueType() != VecVT) {
7536 DCI.AddToWorklist(
Op.getNode());
7546SDValue SystemZTargetLowering::combineTruncateExtract(
7555 if (canTreatAsByteVector(VecVT)) {
7559 if (BytesPerElement % TruncBytes == 0) {
7565 unsigned Scale = BytesPerElement / TruncBytes;
7566 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7573 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7574 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7582SDValue SystemZTargetLowering::combineZERO_EXTEND(
7583 SDNode *
N, DAGCombinerInfo &DCI)
const {
7585 SelectionDAG &DAG = DCI.DAG;
7587 EVT VT =
N->getValueType(0);
7588 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7591 if (TrueOp && FalseOp) {
7601 DCI.CombineTo(N0.
getNode(), TruncSelect);
7644 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7662SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7663 SDNode *
N, DAGCombinerInfo &DCI)
const {
7667 SelectionDAG &DAG = DCI.DAG;
7669 EVT VT =
N->getValueType(0);
7683SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7684 SDNode *
N, DAGCombinerInfo &DCI)
const {
7688 SelectionDAG &DAG = DCI.DAG;
7690 EVT VT =
N->getValueType(0);
7697 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7698 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7714SDValue SystemZTargetLowering::combineMERGE(
7715 SDNode *
N, DAGCombinerInfo &DCI)
const {
7716 SelectionDAG &DAG = DCI.DAG;
7717 unsigned Opcode =
N->getOpcode();
7725 if (Op1 ==
N->getOperand(0))
7730 if (ElemBytes <= 4) {
7731 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7732 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7737 Op1 = DAG.
getNode(ISD::BITCAST, SDLoc(
N), InVT, Op1);
7738 DCI.AddToWorklist(Op1.
getNode());
7741 DCI.AddToWorklist(
Op.getNode());
7742 return DAG.
getNode(ISD::BITCAST, SDLoc(
N), VT,
Op);
7750 LoPart = HiPart =
nullptr;
7755 if (
Use.getResNo() != 0)
7760 bool IsLoPart =
true;
7785 LoPart = HiPart =
nullptr;
7790 if (
Use.getResNo() != 0)
7796 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7799 switch (
User->getConstantOperandVal(1)) {
7800 case SystemZ::subreg_l64:
7805 case SystemZ::subreg_h64:
7817SDValue SystemZTargetLowering::combineLOAD(
7818 SDNode *
N, DAGCombinerInfo &DCI)
const {
7819 SelectionDAG &DAG = DCI.DAG;
7820 EVT LdVT =
N->getValueType(0);
7824 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7825 if (PtrVT != LoadNodeVT) {
7829 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7830 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7831 LN->getMemOperand());
7841 SDNode *LoPart, *HiPart;
7849 LD->getPointerInfo(),
LD->getBaseAlign(),
7850 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7852 DCI.CombineTo(HiPart, EltLoad,
true);
7859 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7860 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7862 DCI.CombineTo(LoPart, EltLoad,
true);
7869 DCI.AddToWorklist(Chain.
getNode());
7884 for (SDUse &Use :
N->uses()) {
7885 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
7889 }
else if (
Use.getResNo() == 0)
7892 if (!Replicate || OtherUses.
empty())
7898 for (SDNode *U : OtherUses) {
7901 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
7907bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
7908 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
7910 if (Subtarget.hasVectorEnhancements2())
7911 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
7923 for (
unsigned i = 0; i < NumElts; ++i) {
7924 if (M[i] < 0)
continue;
7925 if ((
unsigned) M[i] != NumElts - 1 - i)
7933 for (
auto *U : StoredVal->
users()) {
7935 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
7994SDValue SystemZTargetLowering::combineSTORE(
7995 SDNode *
N, DAGCombinerInfo &DCI)
const {
7996 SelectionDAG &DAG = DCI.DAG;
7999 EVT MemVT = SN->getMemoryVT();
8003 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8004 if (PtrVT != StoreNodeVT) {
8008 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8009 SN->getPointerInfo(), SN->getBaseAlign(),
8010 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8018 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8020 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8021 DCI.AddToWorklist(
Value.getNode());
8025 SN->getBasePtr(), SN->getMemoryVT(),
8026 SN->getMemOperand());
8030 if (!SN->isTruncatingStore() &&
8046 Ops, MemVT, SN->getMemOperand());
8049 if (!SN->isTruncatingStore() &&
8052 Subtarget.hasVectorEnhancements2()) {
8054 ArrayRef<int> ShuffleMask = SVN->
getMask();
8062 Ops, MemVT, SN->getMemOperand());
8067 if (!SN->isTruncatingStore() &&
8068 Op1.
getOpcode() == ISD::READCYCLECOUNTER &&
8070 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8074 Ops, MemVT, SN->getMemOperand());
8084 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8085 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8087 SN->getChain(),
DL, LoPart,
8089 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8090 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8108 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8110 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8114 APInt Val =
C->getAPIntValue();
8117 assert(SN->isTruncatingStore() &&
8118 "Non-truncating store and immediate value does not fit?");
8119 Val = Val.
trunc(TotBytes * 8);
8122 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8123 if (VCI.isVectorConstantLegal(Subtarget) &&
8124 VCI.Opcode == SystemZISD::REPLICATE) {
8132 auto FindReplicatedReg = [&](
SDValue MulOp) {
8133 EVT MulVT = MulOp.getValueType();
8134 if (MulOp->getOpcode() ==
ISD::MUL &&
8135 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8139 WordVT =
LHS->getOperand(0).getValueType();
8146 SystemZVectorConstantInfo VCI(
8148 if (VCI.isVectorConstantLegal(Subtarget) &&
8149 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8150 WordVT == VCI.VecVT.getScalarType())
8162 FindReplicatedReg(SplatVal);
8167 FindReplicatedReg(Op1);
8172 "Bad type handling");
8176 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8177 SN->getBasePtr(), SN->getMemOperand());
8184SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8185 SDNode *
N, DAGCombinerInfo &DCI)
const {
8186 SelectionDAG &DAG = DCI.DAG;
8189 N->getOperand(0).hasOneUse() &&
8190 Subtarget.hasVectorEnhancements2()) {
8192 ArrayRef<int> ShuffleMask = SVN->
getMask();
8205 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8209 DCI.CombineTo(
N, ESLoad);
8213 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8223SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8224 SDNode *
N, DAGCombinerInfo &DCI)
const {
8225 SelectionDAG &DAG = DCI.DAG;
8227 if (!Subtarget.hasVector())
8232 if (
Op.getOpcode() == ISD::BITCAST &&
8233 Op.getValueType().isVector() &&
8234 Op.getOperand(0).getValueType().isVector() &&
8235 Op.getValueType().getVectorNumElements() ==
8236 Op.getOperand(0).getValueType().getVectorNumElements())
8237 Op =
Op.getOperand(0);
8241 EVT VecVT =
Op.getValueType();
8244 Op.getOperand(0),
N->getOperand(1));
8245 DCI.AddToWorklist(
Op.getNode());
8247 if (EltVT !=
N->getValueType(0)) {
8248 DCI.AddToWorklist(
Op.getNode());
8249 Op = DAG.
getNode(ISD::BITCAST, SDLoc(
N),
N->getValueType(0),
Op);
8258 if (canTreatAsByteVector(VecVT))
8259 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8260 IndexN->getZExtValue(), DCI,
false);
8265SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8266 SDNode *
N, DAGCombinerInfo &DCI)
const {
8267 SelectionDAG &DAG = DCI.DAG;
8269 if (
N->getOperand(0) ==
N->getOperand(1))
8270 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8280 if (Chain1 == Chain2)
8288SDValue SystemZTargetLowering::combineFP_ROUND(
8289 SDNode *
N, DAGCombinerInfo &DCI)
const {
8291 if (!Subtarget.hasVector())
8300 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8301 SelectionDAG &DAG = DCI.DAG;
8303 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8309 for (
auto *U : Vec->
users()) {
8310 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8312 U->getOperand(0) == Vec &&
8314 U->getConstantOperandVal(1) == 1) {
8316 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8320 if (
N->isStrictFPOpcode()) {
8324 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8325 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8328 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8330 DCI.AddToWorklist(VRound.
getNode());
8334 DCI.AddToWorklist(Extract1.
getNode());
8340 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8343 N->getVTList(), Extract0, Chain);
8352SDValue SystemZTargetLowering::combineFP_EXTEND(
8353 SDNode *
N, DAGCombinerInfo &DCI)
const {
8355 if (!Subtarget.hasVector())
8364 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8365 SelectionDAG &DAG = DCI.DAG;
8367 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8373 for (
auto *U : Vec->
users()) {
8374 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8376 U->getOperand(0) == Vec &&
8378 U->getConstantOperandVal(1) == 2) {
8380 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8384 if (
N->isStrictFPOpcode()) {
8388 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8389 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8392 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8394 DCI.AddToWorklist(VExtend.
getNode());
8398 DCI.AddToWorklist(Extract1.
getNode());
8404 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8407 N->getVTList(), Extract0, Chain);
8416SDValue SystemZTargetLowering::combineINT_TO_FP(
8417 SDNode *
N, DAGCombinerInfo &DCI)
const {
8420 SelectionDAG &DAG = DCI.DAG;
8422 unsigned Opcode =
N->getOpcode();
8423 EVT OutVT =
N->getValueType(0);
8427 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8433 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8434 OutScalarBits <= 64) {
8438 unsigned ExtOpcode =
8441 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8446SDValue SystemZTargetLowering::combineFCOPYSIGN(
8447 SDNode *
N, DAGCombinerInfo &DCI)
const {
8448 SelectionDAG &DAG = DCI.DAG;
8449 EVT VT =
N->getValueType(0);
8462SDValue SystemZTargetLowering::combineBSWAP(
8463 SDNode *
N, DAGCombinerInfo &DCI)
const {
8464 SelectionDAG &DAG = DCI.DAG;
8467 N->getOperand(0).hasOneUse() &&
8468 canLoadStoreByteSwapped(
N->getValueType(0))) {
8477 EVT LoadVT =
N->getValueType(0);
8478 if (LoadVT == MVT::i16)
8483 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8487 if (
N->getValueType(0) == MVT::i16)
8492 DCI.CombineTo(
N, ResVal);
8496 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8504 if (
Op.getOpcode() == ISD::BITCAST &&
8505 Op.getValueType().isVector() &&
8506 Op.getOperand(0).getValueType().isVector() &&
8507 Op.getValueType().getVectorNumElements() ==
8508 Op.getOperand(0).getValueType().getVectorNumElements())
8509 Op =
Op.getOperand(0);
8521 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8523 EVT VecVT =
N->getValueType(0);
8526 Vec = DAG.
getNode(ISD::BITCAST, SDLoc(
N), VecVT, Vec);
8527 DCI.AddToWorklist(Vec.
getNode());
8530 Elt = DAG.
getNode(ISD::BITCAST, SDLoc(
N), EltVT, Elt);
8531 DCI.AddToWorklist(Elt.
getNode());
8534 DCI.AddToWorklist(Vec.
getNode());
8536 DCI.AddToWorklist(Elt.
getNode());
8544 if (SV &&
Op.hasOneUse()) {
8552 EVT VecVT =
N->getValueType(0);
8554 Op0 = DAG.
getNode(ISD::BITCAST, SDLoc(
N), VecVT, Op0);
8555 DCI.AddToWorklist(Op0.
getNode());
8558 Op1 = DAG.
getNode(ISD::BITCAST, SDLoc(
N), VecVT, Op1);
8559 DCI.AddToWorklist(Op1.
getNode());
8562 DCI.AddToWorklist(Op0.
getNode());
8564 DCI.AddToWorklist(Op1.
getNode());
8572SDValue SystemZTargetLowering::combineSETCC(
8573 SDNode *
N, DAGCombinerInfo &DCI)
const {
8574 SelectionDAG &DAG = DCI.DAG;
8580 EVT VT =
N->getValueType(0);
8590 Src.getValueType().isFixedLengthVector() &&
8591 Src.getValueType().getScalarType() == MVT::i1) {
8592 EVT CmpVT = Src.getOperand(0).getValueType();
8612 case SystemZISD::IPM:
8617 case SystemZISD::SELECT_CCMASK: {
8619 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8620 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8623 return std::make_pair(OpCC, OpCCValid);
8628 int CCValidVal = CCValid->getZExtValue();
8629 return std::make_pair(Op4CCReg, CCValidVal);
8640 return std::make_pair(Op0CC, Op0CCValid);
8656 return {Val, Val, Val, Val};
8657 case SystemZISD::IPM: {
8662 for (
auto CC : {0, 1, 2, 3})
8665 return ShiftedCCVals;
8667 case SystemZISD::SELECT_CCMASK: {
8671 if (!CCValid || !CCMask)
8674 int CCValidVal = CCValid->getZExtValue();
8675 int CCMaskVal = CCMask->getZExtValue();
8685 if (TrueSDVals.empty() || FalseSDVals.empty())
8688 for (
auto &CCVal : {0, 1, 2, 3})
8689 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8691 : FalseSDVals[CCVal]);
8692 return MergedSDVals;
8709 if (Op0SDVals.empty() || Op1SDVals.empty())
8712 for (
auto CCVal : {0, 1, 2, 3})
8714 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8715 return BinaryOpSDVals;
8726 auto *CCNode = CCReg.
getNode();
8730 if (CCNode->getOpcode() == SystemZISD::TM) {
8733 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8736 if (!Op0Node || !Op1Node)
8738 auto Op0APVal = Op0Node->getAPIntValue();
8739 auto Op1APVal = Op1Node->getAPIntValue();
8740 auto Result = Op0APVal & Op1APVal;
8741 bool AllOnes = Result == Op1APVal;
8742 bool AllZeros = Result == 0;
8743 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits()] != 0;
8744 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8748 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8753 if (Op0SDVals.empty() || Op1SDVals.empty())
8756 for (
auto CC : {0, 1, 2, 3}) {
8757 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8761 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8763 NewCCMask &= Op0CCValid;
8766 CCValid = Op0CCValid;
8769 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8776 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8780 if (Op0SDVals.empty() || Op1SDVals.empty())
8784 auto CmpTypeVal = CmpType->getZExtValue();
8785 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8789 if (!Op0Node || !Op1Node)
8791 auto Op0APVal = Op0Node->getAPIntValue();
8792 auto Op1APVal = Op1Node->getAPIntValue();
8794 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8795 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8798 for (
auto CC : {0, 1, 2, 3}) {
8799 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8803 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8805 NewCCMask &= Op0CCValid;
8808 CCValid = Op0CCValid;
8819 const Value *Rhs)
const {
8820 const auto isFlagOutOpCC = [](
const Value *V) {
8822 const Value *RHSVal;
8829 if (CB->isInlineAsm()) {
8831 return IA && IA->getConstraintString().contains(
"{@cc}");
8842 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8845 return {-1, -1, -1};
8849 DAGCombinerInfo &DCI)
const {
8855 if (!CCValid || !CCMask)
8858 int CCValidVal = CCValid->getZExtValue();
8859 int CCMaskVal = CCMask->getZExtValue();
8863 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
8867 N->getOperand(3), CCReg);
8871SDValue SystemZTargetLowering::combineSELECT_CCMASK(
8872 SDNode *
N, DAGCombinerInfo &DCI)
const {
8878 if (!CCValid || !CCMask)
8881 int CCValidVal = CCValid->getZExtValue();
8882 int CCMaskVal = CCMask->getZExtValue();
8885 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
8889 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
8890 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
8892 if (Val.getOperand(4) != CCReg)
8899 int CCMaskVal = CCMask->getZExtValue();
8900 for (
auto &CC : {0, 1, 2, 3})
8901 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
8915 if (TrueSDVals.empty())
8916 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
8917 if (FalseSDVals.empty())
8918 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
8919 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
8920 SmallSet<SDValue, 4> MergedSDValsSet;
8922 for (
auto CC : {0, 1, 2, 3}) {
8923 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
8924 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
8928 if (MergedSDValsSet.
size() == 1)
8929 return *MergedSDValsSet.
begin();
8930 if (MergedSDValsSet.
size() == 2) {
8931 auto BeginIt = MergedSDValsSet.
begin();
8932 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
8933 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
8936 for (
auto CC : {0, 1, 2, 3}) {
8938 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
8939 ? (TrueSDVals[CC] == NewTrueVal)
8940 : (FalseSDVals[CC] == NewTrueVal);
8942 CCMaskVal = NewCCMask;
8943 CCMaskVal &= CCValidVal;
8946 IsCombinedCCReg =
true;
8950 if (IsCombinedCCReg)
8952 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
8959SDValue SystemZTargetLowering::combineGET_CCMASK(
8960 SDNode *
N, DAGCombinerInfo &DCI)
const {
8965 if (!CCValid || !CCMask)
8967 int CCValidVal = CCValid->getZExtValue();
8968 int CCMaskVal = CCMask->getZExtValue();
8973 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
8978 if (!SelectCCValid || !SelectCCMask)
8980 int SelectCCValidVal = SelectCCValid->getZExtValue();
8981 int SelectCCMaskVal = SelectCCMask->getZExtValue();
8985 if (!TrueVal || !FalseVal)
8989 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
8990 SelectCCMaskVal ^= SelectCCValidVal;
8994 if (SelectCCValidVal & ~CCValidVal)
8996 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
8999 return Select->getOperand(4);
9002SDValue SystemZTargetLowering::combineIntDIVREM(
9003 SDNode *
N, DAGCombinerInfo &DCI)
const {
9004 SelectionDAG &DAG = DCI.DAG;
9005 EVT VT =
N->getValueType(0);
9022SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9023 SDNode *
N, DAGCombinerInfo &DCI)
const {
9024 SelectionDAG &DAG = DCI.DAG;
9028 "SRL or SRA node is required here!");
9030 if (!Subtarget.hasVector())
9040 SDValue ShiftOperand =
N->getOperand(0);
9060 if (!IsSignExt && !IsZeroExt)
9068 unsigned ActiveBits = IsSignExt
9069 ?
Constant->getAPIntValue().getSignificantBits()
9070 :
Constant->getAPIntValue().getActiveBits();
9071 if (ActiveBits > NarrowVTSize)
9087 unsigned ActiveBits = IsSignExt
9088 ?
Constant->getAPIntValue().getSignificantBits()
9089 :
Constant->getAPIntValue().getActiveBits();
9090 if (ActiveBits > NarrowVTSize)
9107 "Cannot have a multiply node with two different operand types.");
9109 "Cannot have an add node with two different operand types.");
9120 if (ShiftAmt != NarrowVTSize)
9124 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9125 NarrowVT == MVT::v4i32 ||
9126 (Subtarget.hasVectorEnhancements3() &&
9127 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9133 MulhRightOp, MulhAddOp);
9134 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9145 EVT VT =
Op.getValueType();
9154 Op =
Op.getOperand(0);
9155 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9159 bool CanUseEven =
true, CanUseOdd =
true;
9160 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9161 if (ShuffleMask[Elt] == -1)
9163 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9165 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9168 Op =
Op.getOperand(0);
9170 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9172 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9178 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9182 Op =
Op.getOperand(0);
9184 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9186 unsigned Elem =
Op.getConstantOperandVal(1);
9187 Op =
Op.getOperand(0);
9189 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9191 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9198SDValue SystemZTargetLowering::combineMUL(
9199 SDNode *
N, DAGCombinerInfo &DCI)
const {
9200 SelectionDAG &DAG = DCI.DAG;
9207 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9208 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9213SDValue SystemZTargetLowering::combineINTRINSIC(
9214 SDNode *
N, DAGCombinerInfo &DCI)
const {
9215 SelectionDAG &DAG = DCI.DAG;
9217 unsigned Id =
N->getConstantOperandVal(1);
9221 case Intrinsic::s390_vll:
9222 case Intrinsic::s390_vlrl:
9224 if (
C->getZExtValue() >= 15)
9225 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9226 N->getOperand(3), MachinePointerInfo());
9229 case Intrinsic::s390_vstl:
9230 case Intrinsic::s390_vstrl:
9232 if (
C->getZExtValue() >= 15)
9233 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9234 N->getOperand(4), MachinePointerInfo());
9242 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9249 switch(
N->getOpcode()) {
9254 case SystemZISD::MERGE_HIGH:
9255 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9256 case ISD::LOAD:
return combineLOAD(
N, DCI);
9257 case ISD::STORE:
return combineSTORE(
N, DCI);
9260 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9264 case ISD::FP_EXTEND:
return combineFP_EXTEND(
N, DCI);
9270 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9271 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9274 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9275 case ISD::MUL:
return combineMUL(
N, DCI);
9279 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9291 EVT VT =
Op.getValueType();
9294 unsigned Opcode =
Op.getOpcode();
9296 unsigned Id =
Op.getConstantOperandVal(0);
9298 case Intrinsic::s390_vpksh:
9299 case Intrinsic::s390_vpksf:
9300 case Intrinsic::s390_vpksg:
9301 case Intrinsic::s390_vpkshs:
9302 case Intrinsic::s390_vpksfs:
9303 case Intrinsic::s390_vpksgs:
9304 case Intrinsic::s390_vpklsh:
9305 case Intrinsic::s390_vpklsf:
9306 case Intrinsic::s390_vpklsg:
9307 case Intrinsic::s390_vpklshs:
9308 case Intrinsic::s390_vpklsfs:
9309 case Intrinsic::s390_vpklsgs:
9311 SrcDemE = DemandedElts;
9314 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9317 case Intrinsic::s390_vuphb:
9318 case Intrinsic::s390_vuphh:
9319 case Intrinsic::s390_vuphf:
9320 case Intrinsic::s390_vuplhb:
9321 case Intrinsic::s390_vuplhh:
9322 case Intrinsic::s390_vuplhf:
9323 SrcDemE =
APInt(NumElts * 2, 0);
9326 case Intrinsic::s390_vuplb:
9327 case Intrinsic::s390_vuplhw:
9328 case Intrinsic::s390_vuplf:
9329 case Intrinsic::s390_vupllb:
9330 case Intrinsic::s390_vupllh:
9331 case Intrinsic::s390_vupllf:
9332 SrcDemE =
APInt(NumElts * 2, 0);
9335 case Intrinsic::s390_vpdi: {
9337 SrcDemE =
APInt(NumElts, 0);
9338 if (!DemandedElts[OpNo - 1])
9340 unsigned Mask =
Op.getConstantOperandVal(3);
9341 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9343 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9346 case Intrinsic::s390_vsldb: {
9348 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9349 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9350 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9351 unsigned NumSrc0Els = 16 - FirstIdx;
9352 SrcDemE =
APInt(NumElts, 0);
9354 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9357 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9362 case Intrinsic::s390_vperm:
9371 case SystemZISD::JOIN_DWORDS:
9373 SrcDemE =
APInt(1, 1);
9375 case SystemZISD::SELECT_CCMASK:
9376 SrcDemE = DemandedElts;
9387 const APInt &DemandedElts,
9402 const APInt &DemandedElts,
9404 unsigned Depth)
const {
9408 unsigned Tmp0, Tmp1;
9413 EVT VT =
Op.getValueType();
9414 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9417 "KnownBits does not match VT in bitwidth");
9420 "DemandedElts does not match VT number of elements");
9422 unsigned Opcode =
Op.getOpcode();
9424 bool IsLogical =
false;
9425 unsigned Id =
Op.getConstantOperandVal(0);
9427 case Intrinsic::s390_vpksh:
9428 case Intrinsic::s390_vpksf:
9429 case Intrinsic::s390_vpksg:
9430 case Intrinsic::s390_vpkshs:
9431 case Intrinsic::s390_vpksfs:
9432 case Intrinsic::s390_vpksgs:
9433 case Intrinsic::s390_vpklsh:
9434 case Intrinsic::s390_vpklsf:
9435 case Intrinsic::s390_vpklsg:
9436 case Intrinsic::s390_vpklshs:
9437 case Intrinsic::s390_vpklsfs:
9438 case Intrinsic::s390_vpklsgs:
9439 case Intrinsic::s390_vpdi:
9440 case Intrinsic::s390_vsldb:
9441 case Intrinsic::s390_vperm:
9444 case Intrinsic::s390_vuplhb:
9445 case Intrinsic::s390_vuplhh:
9446 case Intrinsic::s390_vuplhf:
9447 case Intrinsic::s390_vupllb:
9448 case Intrinsic::s390_vupllh:
9449 case Intrinsic::s390_vupllf:
9452 case Intrinsic::s390_vuphb:
9453 case Intrinsic::s390_vuphh:
9454 case Intrinsic::s390_vuphf:
9455 case Intrinsic::s390_vuplb:
9456 case Intrinsic::s390_vuplhw:
9457 case Intrinsic::s390_vuplf: {
9472 case SystemZISD::JOIN_DWORDS:
9473 case SystemZISD::SELECT_CCMASK:
9476 case SystemZISD::REPLICATE: {
9499 if (
LHS == 1)
return 1;
9502 if (
RHS == 1)
return 1;
9503 unsigned Common = std::min(
LHS,
RHS);
9504 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9505 EVT VT =
Op.getValueType();
9507 if (SrcBitWidth > VTBits) {
9508 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9509 if (Common > SrcExtraBits)
9510 return (Common - SrcExtraBits);
9513 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9520 unsigned Depth)
const {
9521 if (
Op.getResNo() != 0)
9523 unsigned Opcode =
Op.getOpcode();
9525 unsigned Id =
Op.getConstantOperandVal(0);
9527 case Intrinsic::s390_vpksh:
9528 case Intrinsic::s390_vpksf:
9529 case Intrinsic::s390_vpksg:
9530 case Intrinsic::s390_vpkshs:
9531 case Intrinsic::s390_vpksfs:
9532 case Intrinsic::s390_vpksgs:
9533 case Intrinsic::s390_vpklsh:
9534 case Intrinsic::s390_vpklsf:
9535 case Intrinsic::s390_vpklsg:
9536 case Intrinsic::s390_vpklshs:
9537 case Intrinsic::s390_vpklsfs:
9538 case Intrinsic::s390_vpklsgs:
9539 case Intrinsic::s390_vpdi:
9540 case Intrinsic::s390_vsldb:
9541 case Intrinsic::s390_vperm:
9543 case Intrinsic::s390_vuphb:
9544 case Intrinsic::s390_vuphh:
9545 case Intrinsic::s390_vuphf:
9546 case Intrinsic::s390_vuplb:
9547 case Intrinsic::s390_vuplhw:
9548 case Intrinsic::s390_vuplf: {
9552 EVT VT =
Op.getValueType();
9562 case SystemZISD::SELECT_CCMASK:
9576 switch (
Op->getOpcode()) {
9577 case SystemZISD::PCREL_WRAPPER:
9578 case SystemZISD::PCREL_OFFSET:
9589 "Unexpected stack alignment");
9592 unsigned StackProbeSize =
9595 StackProbeSize &= ~(StackAlign - 1);
9596 return StackProbeSize ? StackProbeSize : StackAlign;
9613 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9619 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9635 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9637 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9643 if (miI ==
MBB->end()) {
9645 if (Succ->isLiveIn(SystemZ::CC))
9656 switch (
MI.getOpcode()) {
9657 case SystemZ::Select32:
9658 case SystemZ::Select64:
9659 case SystemZ::Select128:
9660 case SystemZ::SelectF32:
9661 case SystemZ::SelectF64:
9662 case SystemZ::SelectF128:
9663 case SystemZ::SelectVR32:
9664 case SystemZ::SelectVR64:
9665 case SystemZ::SelectVR128:
9697 for (
auto *
MI : Selects) {
9698 Register DestReg =
MI->getOperand(0).getReg();
9699 Register TrueReg =
MI->getOperand(1).getReg();
9700 Register FalseReg =
MI->getOperand(2).getReg();
9705 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9708 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9709 TrueReg = It->second.first;
9711 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9712 FalseReg = It->second.second;
9715 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9720 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9731 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9732 assert(TFL->hasReservedCallFrame(MF) &&
9733 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9738 uint32_t NumBytes =
MI.getOperand(0).getImm();
9743 MI.eraseFromParent();
9752 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9754 unsigned CCValid =
MI.getOperand(3).getImm();
9755 unsigned CCMask =
MI.getOperand(4).getImm();
9760 SmallVector<MachineInstr*, 8> Selects;
9761 SmallVector<MachineInstr*, 8> DbgValues;
9767 assert(NextMI.getOperand(3).getImm() == CCValid &&
9768 "Bad CCValid operands since CC was not redefined.");
9769 if (NextMI.getOperand(4).getImm() == CCMask ||
9770 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9776 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9777 NextMI.usesCustomInsertionHook())
9780 for (
auto *SelMI : Selects)
9781 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9785 if (NextMI.isDebugInstr()) {
9787 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9790 }
else if (User || ++
Count > 20)
9794 MachineInstr *LastMI = Selects.back();
9795 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9797 MachineBasicBlock *StartMBB =
MBB;
9827 for (
auto *SelMI : Selects)
9828 SelMI->eraseFromParent();
9831 for (
auto *DbgMI : DbgValues)
9832 MBB->
splice(InsertPos, StartMBB, DbgMI);
9843 unsigned StoreOpcode,
9844 unsigned STOCOpcode,
9845 bool Invert)
const {
9846 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9849 MachineOperand
Base =
MI.getOperand(1);
9850 int64_t Disp =
MI.getOperand(2).getImm();
9851 Register IndexReg =
MI.getOperand(3).getReg();
9852 unsigned CCValid =
MI.getOperand(4).getImm();
9853 unsigned CCMask =
MI.getOperand(5).getImm();
9856 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
9860 MachineMemOperand *MMO =
nullptr;
9861 for (
auto *
I :
MI.memoperands())
9870 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
9882 MI.eraseFromParent();
9890 MachineBasicBlock *StartMBB =
MBB;
9896 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
9923 MI.eraseFromParent();
9933 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9941 MachineBasicBlock *StartMBB =
MBB;
9959 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
9978 Register Temp =
MRI.createVirtualRegister(&SystemZ::VR128BitRegClass);
9986 MI.eraseFromParent();
9997 bool Invert)
const {
9999 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10006 int64_t Disp =
MI.getOperand(2).getImm();
10008 Register BitShift =
MI.getOperand(4).getReg();
10009 Register NegBitShift =
MI.getOperand(5).getReg();
10010 unsigned BitSize =
MI.getOperand(6).getImm();
10014 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10015 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10016 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10019 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10020 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10021 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10022 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10023 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10026 MachineBasicBlock *StartMBB =
MBB;
10054 Register Tmp =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10059 }
else if (BinOpcode)
10082 MI.eraseFromParent();
10093 unsigned KeepOldMask)
const {
10095 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10101 int64_t Disp =
MI.getOperand(2).getImm();
10103 Register BitShift =
MI.getOperand(4).getReg();
10104 Register NegBitShift =
MI.getOperand(5).getReg();
10105 unsigned BitSize =
MI.getOperand(6).getImm();
10109 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10110 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10111 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10114 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10115 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10116 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10117 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10118 Register RotatedAltVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10119 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10122 MachineBasicBlock *StartMBB =
MBB;
10186 MI.eraseFromParent();
10196 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10202 int64_t Disp =
MI.getOperand(2).getImm();
10203 Register CmpVal =
MI.getOperand(3).getReg();
10204 Register OrigSwapVal =
MI.getOperand(4).getReg();
10205 Register BitShift =
MI.getOperand(5).getReg();
10206 Register NegBitShift =
MI.getOperand(6).getReg();
10207 int64_t BitSize =
MI.getOperand(7).getImm();
10210 const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
10213 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10214 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10215 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10216 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10219 Register OrigOldVal =
MRI.createVirtualRegister(RC);
10221 Register SwapVal =
MRI.createVirtualRegister(RC);
10222 Register StoreVal =
MRI.createVirtualRegister(RC);
10223 Register OldValRot =
MRI.createVirtualRegister(RC);
10224 Register RetryOldVal =
MRI.createVirtualRegister(RC);
10225 Register RetrySwapVal =
MRI.createVirtualRegister(RC);
10228 MachineBasicBlock *StartMBB =
MBB;
10300 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10303 MI.eraseFromParent();
10311 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10316 .
add(
MI.getOperand(1))
10317 .
addImm(SystemZ::subreg_h64)
10318 .
add(
MI.getOperand(2))
10319 .
addImm(SystemZ::subreg_l64);
10320 MI.eraseFromParent();
10329 bool ClearEven)
const {
10331 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10337 Register In128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10341 Register NewIn128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10342 Register Zero64 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10353 MI.eraseFromParent();
10360 unsigned Opcode,
bool IsMemset)
const {
10362 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10367 uint64_t DestDisp =
MI.getOperand(1).getImm();
10372 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10374 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10375 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10385 SrcDisp =
MI.getOperand(3).getImm();
10387 SrcBase = DestBase;
10388 SrcDisp = DestDisp++;
10389 foldDisplIfNeeded(DestBase, DestDisp);
10392 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10393 bool IsImmForm = LengthMO.
isImm();
10394 bool IsRegForm = !IsImmForm;
10397 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10399 MachineOperand DBase, uint64_t DDisp,
10400 MachineOperand
SBase, uint64_t SDisp,
10401 unsigned Length) ->
void {
10405 if (ByteMO.
isImm())
10420 bool NeedsLoop =
false;
10421 uint64_t ImmLength = 0;
10422 Register LenAdjReg = SystemZ::NoRegister;
10424 ImmLength = LengthMO.
getImm();
10425 ImmLength += IsMemset ? 2 : 1;
10426 if (ImmLength == 0) {
10427 MI.eraseFromParent();
10430 if (Opcode == SystemZ::CLC) {
10431 if (ImmLength > 3 * 256)
10441 }
else if (ImmLength > 6 * 256)
10449 LenAdjReg = LengthMO.
getReg();
10454 MachineBasicBlock *EndMBB =
10455 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10461 MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10463 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10473 auto loadZeroAddress = [&]() -> MachineOperand {
10474 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10478 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10479 DestBase = loadZeroAddress();
10480 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10481 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10483 MachineBasicBlock *StartMBB =
nullptr;
10484 MachineBasicBlock *LoopMBB =
nullptr;
10485 MachineBasicBlock *NextMBB =
nullptr;
10486 MachineBasicBlock *DoneMBB =
nullptr;
10487 MachineBasicBlock *AllDoneMBB =
nullptr;
10491 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10493 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
10494 Register ThisSrcReg =
MRI.createVirtualRegister(RC);
10496 (HaveSingleBase ? ThisSrcReg :
MRI.createVirtualRegister(RC));
10497 Register NextSrcReg =
MRI.createVirtualRegister(RC);
10499 (HaveSingleBase ? NextSrcReg :
MRI.createVirtualRegister(RC));
10500 RC = &SystemZ::GR64BitRegClass;
10501 Register ThisCountReg =
MRI.createVirtualRegister(RC);
10502 Register NextCountReg =
MRI.createVirtualRegister(RC);
10528 MBB = MemsetOneCheckMBB;
10539 MBB = MemsetOneMBB;
10571 if (EndMBB && !ImmLength)
10593 if (!HaveSingleBase)
10600 if (Opcode == SystemZ::MVC)
10627 if (!HaveSingleBase)
10649 Register RemSrcReg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10650 Register RemDestReg = HaveSingleBase ? RemSrcReg
10651 :
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10655 if (!HaveSingleBase)
10663 MachineInstrBuilder EXRL_MIB =
10671 if (Opcode != SystemZ::MVC) {
10681 while (ImmLength > 0) {
10682 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10685 foldDisplIfNeeded(DestBase, DestDisp);
10686 foldDisplIfNeeded(SrcBase, SrcDisp);
10687 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10688 DestDisp += ThisLength;
10689 SrcDisp += ThisLength;
10690 ImmLength -= ThisLength;
10693 if (EndMBB && ImmLength > 0) {
10709 MI.eraseFromParent();
10718 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10722 uint64_t End1Reg =
MI.getOperand(0).getReg();
10723 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10724 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10725 uint64_t CharReg =
MI.getOperand(3).getReg();
10727 const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
10728 uint64_t This1Reg =
MRI.createVirtualRegister(RC);
10729 uint64_t This2Reg =
MRI.createVirtualRegister(RC);
10730 uint64_t End2Reg =
MRI.createVirtualRegister(RC);
10732 MachineBasicBlock *StartMBB =
MBB;
10768 MI.eraseFromParent();
10775 bool NoFloat)
const {
10777 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10778 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10781 MI.setDesc(
TII->get(Opcode));
10785 uint64_t Control =
MI.getOperand(2).getImm();
10786 static const unsigned GPRControlBit[16] = {
10787 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10788 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10790 Control |= GPRControlBit[15];
10791 if (TFI->
hasFP(MF))
10792 Control |= GPRControlBit[11];
10793 MI.getOperand(2).setImm(Control);
10796 for (
int I = 0;
I < 16;
I++) {
10797 if ((Control & GPRControlBit[
I]) == 0) {
10804 if (!NoFloat && (Control & 4) != 0) {
10805 if (Subtarget.hasVector()) {
10823 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10826 Register SrcReg =
MI.getOperand(0).getReg();
10829 const TargetRegisterClass *RC =
MRI->getRegClass(SrcReg);
10830 Register DstReg =
MRI->createVirtualRegister(RC);
10837 MI.eraseFromParent();
10846 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10849 Register DstReg =
MI.getOperand(0).getReg();
10850 Register SizeReg =
MI.getOperand(2).getReg();
10852 MachineBasicBlock *StartMBB =
MBB;
10862 Register PHIReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10863 Register IncReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10928 MI.eraseFromParent();
10932SDValue SystemZTargetLowering::
10935 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
10943 switch (
MI.getOpcode()) {
10944 case SystemZ::ADJCALLSTACKDOWN:
10945 case SystemZ::ADJCALLSTACKUP:
10946 return emitAdjCallStack(
MI,
MBB);
10948 case SystemZ::Select32:
10949 case SystemZ::Select64:
10950 case SystemZ::Select128:
10951 case SystemZ::SelectF32:
10952 case SystemZ::SelectF64:
10953 case SystemZ::SelectF128:
10954 case SystemZ::SelectVR32:
10955 case SystemZ::SelectVR64:
10956 case SystemZ::SelectVR128:
10957 return emitSelect(
MI,
MBB);
10959 case SystemZ::CondStore8Mux:
10960 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
10961 case SystemZ::CondStore8MuxInv:
10962 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
10963 case SystemZ::CondStore16Mux:
10964 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
10965 case SystemZ::CondStore16MuxInv:
10966 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
10967 case SystemZ::CondStore32Mux:
10968 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
10969 case SystemZ::CondStore32MuxInv:
10970 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
10971 case SystemZ::CondStore8:
10972 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
10973 case SystemZ::CondStore8Inv:
10974 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
10975 case SystemZ::CondStore16:
10976 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
10977 case SystemZ::CondStore16Inv:
10978 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
10979 case SystemZ::CondStore32:
10980 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
10981 case SystemZ::CondStore32Inv:
10982 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
10983 case SystemZ::CondStore64:
10984 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
10985 case SystemZ::CondStore64Inv:
10986 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
10987 case SystemZ::CondStoreF32:
10988 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
10989 case SystemZ::CondStoreF32Inv:
10990 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
10991 case SystemZ::CondStoreF64:
10992 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
10993 case SystemZ::CondStoreF64Inv:
10994 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
10996 case SystemZ::SCmp128Hi:
10997 return emitICmp128Hi(
MI,
MBB,
false);
10998 case SystemZ::UCmp128Hi:
10999 return emitICmp128Hi(
MI,
MBB,
true);
11001 case SystemZ::PAIR128:
11002 return emitPair128(
MI,
MBB);
11003 case SystemZ::AEXT128:
11004 return emitExt128(
MI,
MBB,
false);
11005 case SystemZ::ZEXT128:
11006 return emitExt128(
MI,
MBB,
true);
11008 case SystemZ::ATOMIC_SWAPW:
11009 return emitAtomicLoadBinary(
MI,
MBB, 0);
11011 case SystemZ::ATOMIC_LOADW_AR:
11012 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11013 case SystemZ::ATOMIC_LOADW_AFI:
11014 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11016 case SystemZ::ATOMIC_LOADW_SR:
11017 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11019 case SystemZ::ATOMIC_LOADW_NR:
11020 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11021 case SystemZ::ATOMIC_LOADW_NILH:
11022 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11024 case SystemZ::ATOMIC_LOADW_OR:
11025 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11026 case SystemZ::ATOMIC_LOADW_OILH:
11027 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11029 case SystemZ::ATOMIC_LOADW_XR:
11030 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11031 case SystemZ::ATOMIC_LOADW_XILF:
11032 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11034 case SystemZ::ATOMIC_LOADW_NRi:
11035 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11036 case SystemZ::ATOMIC_LOADW_NILHi:
11037 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11039 case SystemZ::ATOMIC_LOADW_MIN:
11041 case SystemZ::ATOMIC_LOADW_MAX:
11043 case SystemZ::ATOMIC_LOADW_UMIN:
11045 case SystemZ::ATOMIC_LOADW_UMAX:
11048 case SystemZ::ATOMIC_CMP_SWAPW:
11049 return emitAtomicCmpSwapW(
MI,
MBB);
11050 case SystemZ::MVCImm:
11051 case SystemZ::MVCReg:
11052 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11053 case SystemZ::NCImm:
11054 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11055 case SystemZ::OCImm:
11056 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11057 case SystemZ::XCImm:
11058 case SystemZ::XCReg:
11059 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11060 case SystemZ::CLCImm:
11061 case SystemZ::CLCReg:
11062 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11063 case SystemZ::MemsetImmImm:
11064 case SystemZ::MemsetImmReg:
11065 case SystemZ::MemsetRegImm:
11066 case SystemZ::MemsetRegReg:
11067 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11068 case SystemZ::CLSTLoop:
11069 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11070 case SystemZ::MVSTLoop:
11071 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11072 case SystemZ::SRSTLoop:
11073 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11074 case SystemZ::TBEGIN:
11075 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11076 case SystemZ::TBEGIN_nofloat:
11077 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11078 case SystemZ::TBEGINC:
11079 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11080 case SystemZ::LTEBRCompare_Pseudo:
11081 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11082 case SystemZ::LTDBRCompare_Pseudo:
11083 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11084 case SystemZ::LTXBRCompare_Pseudo:
11085 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11087 case SystemZ::PROBED_ALLOCA:
11088 return emitProbedAlloca(
MI,
MBB);
11089 case SystemZ::EH_SjLj_SetJmp:
11091 case SystemZ::EH_SjLj_LongJmp:
11094 case TargetOpcode::STACKMAP:
11095 case TargetOpcode::PATCHPOINT:
11106SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11107 if (VT == MVT::Untyped)
11108 return &SystemZ::ADDR128BitRegClass;
11134 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11154 EVT VT =
Op.getValueType();
11155 Op =
Op.getOperand(0);
11156 EVT OpVT =
Op.getValueType();
11158 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11169 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11189 const AttributeList &Attrs =
F->getAttributes();
11190 if (Attrs.hasRetAttrs())
11191 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11192 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11193 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11196 OS << *FT->getParamType(
I);
11198 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11205bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11206 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11207 if (Itr == IsInternalCache.end())
11208 Itr = IsInternalCache
11209 .insert(std::pair<const Function *, bool>(
11212 return Itr->second;
11215void SystemZTargetLowering::
11223 bool IsInternal =
false;
11224 const Function *CalleeFn =
nullptr;
11227 IsInternal = isInternal(CalleeFn);
11228 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11229 errs() <<
"ERROR: Missing extension attribute of passed "
11230 <<
"value in call to function:\n" <<
"Callee: ";
11231 if (CalleeFn !=
nullptr)
11235 errs() <<
"Caller: ";
11241void SystemZTargetLowering::
11249 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11250 errs() <<
"ERROR: Missing extension attribute of returned "
11251 <<
"value from function:\n";
11259bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11261 if (!Subtarget.isTargetELF())
11270 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11271 MVT VT = Outs[i].VT;
11272 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11275 "Unexpected integer argument VT.");
11276 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 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.
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
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...
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
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.
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
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
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
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.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
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.
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...
@ 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.
@ ADD
Simple integer binary arithmetic operators.
@ 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...
@ 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.
@ 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.
@ 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.
@ SSUBO
Same for subtraction.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ 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.
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ 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) ...
@ 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.
@ 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.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ 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.
@ 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.
@ 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 ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ 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.
@ 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.