25#include "llvm/IR/IntrinsicsS390.h"
37#define DEBUG_TYPE "systemz-lower"
43 cl::desc(
"Verify that narrow int args are properly extended per the "
50 : Op0(Op0In), Op1(Op1In), Chain(ChainIn),
51 Opcode(0), ICmpType(0), CCValid(0), CCMask(0) {}
101 if (Subtarget.hasHighWord())
107 if (Subtarget.hasVector()) {
116 if (Subtarget.hasVectorEnhancements1())
121 if (Subtarget.hasVector()) {
131 if (Subtarget.hasVector())
158 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
159 I <= MVT::LAST_FP_VALUETYPE;
185 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
186 I <= MVT::LAST_INTEGER_VALUETYPE;
217 if (Subtarget.hasPopulationCount())
243 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
264 if (!Subtarget.hasVectorEnhancements3()) {
291 if (Subtarget.hasVectorEnhancements3()) {
334 {MVT::i8, MVT::i16, MVT::i32},
Legal);
336 {MVT::i8, MVT::i16},
Legal);
357 if (Subtarget.hasMiscellaneousExtensions4()) {
364 if (Subtarget.hasMiscellaneousExtensions3()) {
457 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
462 if (Subtarget.hasVectorEnhancements3() &&
463 VT != MVT::v16i8 && VT != MVT::v8i16) {
473 if (Subtarget.hasVectorEnhancements1())
507 if (Subtarget.hasVector()) {
529 if (Subtarget.hasVectorEnhancements2()) {
555 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
569 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
570 I <= MVT::LAST_FP_VALUETYPE;
578 if (Subtarget.hasFPExtension()) {
606 if (Subtarget.hasFPExtension()) {
622 if (Subtarget.hasVector()) {
673 if (Subtarget.hasVectorEnhancements1()) {
680 if (Subtarget.hasVectorEnhancements1()) {
697 for (
MVT Type : {MVT::f64, MVT::v2f64, MVT::f32, MVT::v4f32, MVT::f128}) {
722 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
723 MVT::v4f32, MVT::v2f64 }) {
734 if (!Subtarget.hasVectorEnhancements1()) {
740 if (Subtarget.hasVectorEnhancements1())
750 if (Subtarget.hasVectorEnhancements1()) {
762 if (!Subtarget.hasVector()) {
773 if (Subtarget.isTargetzOS()) {
838 return Subtarget.hasSoftFloat();
843 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
845 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16)) {
846 IntermediateVT = RegisterVT = MVT::v8f16;
847 return NumIntermediates =
851 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
863 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
871 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
898 return Subtarget.hasVectorEnhancements1();
911 if (!Subtarget.hasVector() ||
912 (isFP128 && !Subtarget.hasVectorEnhancements1()))
921 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
928 Opcode = SystemZISD::BYTE_MASK;
934 if (SplatBitSize > 64)
941 OpVals.push_back(((
unsigned) SignedValue));
942 Opcode = SystemZISD::REPLICATE;
949 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start, End)) {
953 OpVals.push_back(Start - (64 - SplatBitSize));
954 OpVals.push_back(End - (64 - SplatBitSize));
955 Opcode = SystemZISD::ROTATE_MASK;
967 uint64_t SplatBitsZ = SplatBits.getZExtValue();
968 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
980 return TryValue(SplatBitsZ | Middle);
989 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
995 unsigned HalfSize = Width / 2;
1000 if (HighValue != LowValue || 8 > HalfSize)
1003 SplatBits = HighValue;
1007 SplatBitSize = Width;
1015 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1019 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1024 bool ForCodeSize)
const {
1026 if (Imm.isZero() || Imm.isNegZero())
1047 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1053 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1106 const int64_t FPOffset = 0;
1127 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1128 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1131 .
addReg(SpecialRegs->getFramePointerRegister())
1139 .
addReg(SpecialRegs->getStackPointerRegister())
1150 .
addReg(SpecialRegs->getStackPointerRegister())
1151 .
addImm(TFL->getBackchainOffset(*MF))
1162 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1166 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1187 MI.eraseFromParent();
1203 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1206 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1213 const int64_t FPOffset = 0;
1225 SpecialRegs->getFramePointerRegister())
1247 SpecialRegs->getStackPointerRegister())
1256 .
addReg(SpecialRegs->getStackPointerRegister())
1257 .
addImm(TFL->getBackchainOffset(*MF))
1263 MI.eraseFromParent();
1294 if (Subtarget.hasInterlockedAccess1() &&
1327 EVT VT =
Y.getValueType();
1330 if (VT == MVT::i32 || VT == MVT::i64)
1331 return Subtarget.hasMiscellaneousExtensions3();
1334 if (VT.
isVector() || VT == MVT::i128)
1335 return Subtarget.hasVector();
1363 bool MVC = Ty->isIntegerTy(8);
1369static AddressingMode
1372 switch (
II->getIntrinsicID()) {
1374 case Intrinsic::memset:
1375 case Intrinsic::memmove:
1376 case Intrinsic::memcpy:
1383 if (SingleUser->getParent() ==
I->getParent()) {
1386 if (
C->getBitWidth() <= 64 &&
1396 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1410 I->getOperand(0)->getType());
1412 bool IsVectorAccess = MemAccessTy->isVectorTy();
1417 Value *DataOp =
I->getOperand(0);
1419 IsVectorAccess =
true;
1425 User *LoadUser = *
I->user_begin();
1427 IsVectorAccess =
true;
1430 if (IsFPAccess || IsVectorAccess)
1449 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1459 return AM.
Scale == 0;
1466 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1467 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1468 const AttributeList &FuncAttributes,
EVT *LargestVT)
const {
1471 "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
1473 if (
Op.isZeroMemset())
1476 const int MVCFastLen = 16;
1478 if ((
Op.isMemset() ?
Op.size() - 1 :
Op.size()) <= MVCFastLen)
1482 if (!
Op.isAligned(
Align(8)) || (
Op.size() >= 25 &&
Op.size() <= 31))
1486 Context, MemOps, Limit,
Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1491 const AttributeList &FuncAttributes)
const {
1492 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1496 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1498 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1500 return FromBits > ToBits;
1508 return FromBits > ToBits;
1517 if (Constraint.
size() == 1) {
1518 switch (Constraint[0]) {
1544 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1545 switch (Constraint[1]) {
1556 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1566 Value *CallOperandVal = Info.CallOperandVal;
1569 if (!CallOperandVal)
1573 switch (*Constraint) {
1592 if (Subtarget.hasVector())
1623 if (
C->getZExtValue() == 0x7fffffff)
1633static std::pair<unsigned, const TargetRegisterClass *>
1635 const unsigned *Map,
unsigned Size) {
1636 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1637 if (isdigit(Constraint[2])) {
1642 return std::make_pair(Map[Index], RC);
1644 return std::make_pair(0U,
nullptr);
1647std::pair<unsigned, const TargetRegisterClass *>
1650 if (Constraint.
size() == 1) {
1652 switch (Constraint[0]) {
1657 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1659 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1660 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1664 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1665 else if (VT == MVT::i128)
1666 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1667 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1670 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1675 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1677 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1679 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1680 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1685 if (Subtarget.hasVector()) {
1687 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1689 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1691 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1692 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1701 auto getVTSizeInBits = [&VT]() {
1709 if (Constraint[1] ==
'r') {
1710 if (getVTSizeInBits() == 32)
1713 if (getVTSizeInBits() == 128)
1719 if (Constraint[1] ==
'f') {
1721 return std::make_pair(
1723 if (getVTSizeInBits() == 16)
1726 if (getVTSizeInBits() == 32)
1729 if (getVTSizeInBits() == 128)
1735 if (Constraint[1] ==
'v') {
1736 if (!Subtarget.hasVector())
1737 return std::make_pair(
1739 if (getVTSizeInBits() == 16)
1742 if (getVTSizeInBits() == 32)
1745 if (getVTSizeInBits() == 64)
1751 if (Constraint[1] ==
'@') {
1752 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1753 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1766 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1767 : SystemZ::NoRegister)
1769 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1776 const Constant *PersonalityFn)
const {
1777 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1781 const Constant *PersonalityFn)
const {
1782 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1797 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1801 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1802 OpInfo.ConstraintVT.getSizeInBits() < 8)
1817 if (Constraint.
size() == 1) {
1818 switch (Constraint[0]) {
1823 Op.getValueType()));
1830 Op.getValueType()));
1837 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1844 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1849 if (
C->getZExtValue() == 0x7fffffff)
1851 Op.getValueType()));
1862#define GET_CALLING_CONV_IMPL
1863#include "SystemZGenCallingConv.inc"
1867 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1873 Type *ToType)
const {
1936 if (BitCastToType == MVT::v2i64)
1963 MVT::Untyped,
Hi,
Lo);
1987 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1989 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2000 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
2001 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2012template <
class ArgTy>
2015 MVT &PartVT,
unsigned &NumParts) {
2016 if (!Args[
I].Flags.isSplit())
2020 PartVT = ArgLocs[
I].getValVT();
2022 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2023 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2024 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2026 if (Args[PartIdx].Flags.isSplitEnd())
2050 unsigned NumFixedGPRs = 0;
2051 unsigned NumFixedFPRs = 0;
2052 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2065 RC = &SystemZ::GR32BitRegClass;
2069 RC = &SystemZ::GR64BitRegClass;
2073 RC = &SystemZ::FP16BitRegClass;
2077 RC = &SystemZ::FP32BitRegClass;
2081 RC = &SystemZ::FP64BitRegClass;
2085 RC = &SystemZ::FP128BitRegClass;
2094 RC = &SystemZ::VR128BitRegClass;
2108 if (Subtarget.isTargetXPLINK64()) {
2111 ArgSPOffset += XPRegs.getCallFrameSize();
2122 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2126 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2140 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2143 unsigned PartOffset = Ins[
I].PartOffset;
2148 assert(PartOffset &&
"Offset should be non-zero.");
2155 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2161 Subtarget.getSpecialRegisters());
2167 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2172 if (IsVarArg && Subtarget.isTargetELF()) {
2185 int64_t RegSaveOffset =
2200 &SystemZ::FP64BitRegClass);
2212 if (Subtarget.isTargetXPLINK64()) {
2217 Subtarget.getSpecialRegisters());
2218 MRI.
addLiveIn(Regs->getADARegister(), ADAvReg);
2230 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2237 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2239 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2246 unsigned Offset,
bool LoadAdr =
false) {
2269 bool LoadAddr =
false;
2291 unsigned ADADelta = 0;
2292 unsigned EPADelta = 8;
2298 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2299 G->getGlobal()->hasPrivateLinkage());
2306 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2352 if (Subtarget.isTargetXPLINK64())
2356 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2360 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2379 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2387 unsigned NumParts = 1;
2391 SlotVT = Outs[
I].VT;
2398 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2401 assert(Outs[
I].PartOffset == 0);
2402 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2405 unsigned PartOffset = Outs[
I].PartOffset;
2411 assert(PartOffset &&
"Offset should be non-zero.");
2413 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2415 ArgValue = SpillSlot;
2432 if (!StackPtr.getNode())
2439 else if (VA.
getLocVT() == MVT::f16)
2452 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2456 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2462 if (!MemOpChains.
empty())
2470 if (Subtarget.isTargetXPLINK64()) {
2475 ->getAddressOfCalleeRegister();
2478 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2485 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2488 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2489 }
else if (IsTailCall) {
2492 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2497 for (
const auto &[Reg,
N] : RegsToPass) {
2504 Ops.push_back(Chain);
2505 Ops.push_back(Callee);
2509 for (
const auto &[Reg,
N] : RegsToPass)
2514 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2515 assert(Mask &&
"Missing call preserved mask for calling convention");
2520 Ops.push_back(Glue);
2529 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2539 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2546 VA.getLocVT(), Glue);
2563 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2565 Args.reserve(
Ops.size());
2571 Entry.IsZExt = !Entry.IsSExt;
2572 Args.push_back(Entry);
2583 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2594 const Type *RetTy)
const {
2597 for (
auto &Out : Outs)
2598 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2602 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2603 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2615 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2623 if (RetLocs.
empty())
2624 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2633 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2655 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2662 unsigned &CCValid) {
2663 unsigned Id =
Op.getConstantOperandVal(1);
2665 case Intrinsic::s390_tbegin:
2666 Opcode = SystemZISD::TBEGIN;
2670 case Intrinsic::s390_tbegin_nofloat:
2671 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2675 case Intrinsic::s390_tend:
2676 Opcode = SystemZISD::TEND;
2689 unsigned Id =
Op.getConstantOperandVal(0);
2691 case Intrinsic::s390_vpkshs:
2692 case Intrinsic::s390_vpksfs:
2693 case Intrinsic::s390_vpksgs:
2694 Opcode = SystemZISD::PACKS_CC;
2698 case Intrinsic::s390_vpklshs:
2699 case Intrinsic::s390_vpklsfs:
2700 case Intrinsic::s390_vpklsgs:
2701 Opcode = SystemZISD::PACKLS_CC;
2705 case Intrinsic::s390_vceqbs:
2706 case Intrinsic::s390_vceqhs:
2707 case Intrinsic::s390_vceqfs:
2708 case Intrinsic::s390_vceqgs:
2709 case Intrinsic::s390_vceqqs:
2710 Opcode = SystemZISD::VICMPES;
2714 case Intrinsic::s390_vchbs:
2715 case Intrinsic::s390_vchhs:
2716 case Intrinsic::s390_vchfs:
2717 case Intrinsic::s390_vchgs:
2718 case Intrinsic::s390_vchqs:
2719 Opcode = SystemZISD::VICMPHS;
2723 case Intrinsic::s390_vchlbs:
2724 case Intrinsic::s390_vchlhs:
2725 case Intrinsic::s390_vchlfs:
2726 case Intrinsic::s390_vchlgs:
2727 case Intrinsic::s390_vchlqs:
2728 Opcode = SystemZISD::VICMPHLS;
2732 case Intrinsic::s390_vtm:
2733 Opcode = SystemZISD::VTM;
2737 case Intrinsic::s390_vfaebs:
2738 case Intrinsic::s390_vfaehs:
2739 case Intrinsic::s390_vfaefs:
2740 Opcode = SystemZISD::VFAE_CC;
2744 case Intrinsic::s390_vfaezbs:
2745 case Intrinsic::s390_vfaezhs:
2746 case Intrinsic::s390_vfaezfs:
2747 Opcode = SystemZISD::VFAEZ_CC;
2751 case Intrinsic::s390_vfeebs:
2752 case Intrinsic::s390_vfeehs:
2753 case Intrinsic::s390_vfeefs:
2754 Opcode = SystemZISD::VFEE_CC;
2758 case Intrinsic::s390_vfeezbs:
2759 case Intrinsic::s390_vfeezhs:
2760 case Intrinsic::s390_vfeezfs:
2761 Opcode = SystemZISD::VFEEZ_CC;
2765 case Intrinsic::s390_vfenebs:
2766 case Intrinsic::s390_vfenehs:
2767 case Intrinsic::s390_vfenefs:
2768 Opcode = SystemZISD::VFENE_CC;
2772 case Intrinsic::s390_vfenezbs:
2773 case Intrinsic::s390_vfenezhs:
2774 case Intrinsic::s390_vfenezfs:
2775 Opcode = SystemZISD::VFENEZ_CC;
2779 case Intrinsic::s390_vistrbs:
2780 case Intrinsic::s390_vistrhs:
2781 case Intrinsic::s390_vistrfs:
2782 Opcode = SystemZISD::VISTR_CC;
2786 case Intrinsic::s390_vstrcbs:
2787 case Intrinsic::s390_vstrchs:
2788 case Intrinsic::s390_vstrcfs:
2789 Opcode = SystemZISD::VSTRC_CC;
2793 case Intrinsic::s390_vstrczbs:
2794 case Intrinsic::s390_vstrczhs:
2795 case Intrinsic::s390_vstrczfs:
2796 Opcode = SystemZISD::VSTRCZ_CC;
2800 case Intrinsic::s390_vstrsb:
2801 case Intrinsic::s390_vstrsh:
2802 case Intrinsic::s390_vstrsf:
2803 Opcode = SystemZISD::VSTRS_CC;
2807 case Intrinsic::s390_vstrszb:
2808 case Intrinsic::s390_vstrszh:
2809 case Intrinsic::s390_vstrszf:
2810 Opcode = SystemZISD::VSTRSZ_CC;
2814 case Intrinsic::s390_vfcedbs:
2815 case Intrinsic::s390_vfcesbs:
2816 Opcode = SystemZISD::VFCMPES;
2820 case Intrinsic::s390_vfchdbs:
2821 case Intrinsic::s390_vfchsbs:
2822 Opcode = SystemZISD::VFCMPHS;
2826 case Intrinsic::s390_vfchedbs:
2827 case Intrinsic::s390_vfchesbs:
2828 Opcode = SystemZISD::VFCMPHES;
2832 case Intrinsic::s390_vftcidb:
2833 case Intrinsic::s390_vftcisb:
2834 Opcode = SystemZISD::VFTCI;
2838 case Intrinsic::s390_tdc:
2839 Opcode = SystemZISD::TDC;
2852 unsigned NumOps =
Op.getNumOperands();
2855 Ops.push_back(
Op.getOperand(0));
2857 Ops.push_back(
Op.getOperand(
I));
2859 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2873 unsigned NumOps =
Op.getNumOperands();
2879 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2880 "Unhandled intrinsic with f16 operand.");
2883 Ops.push_back(CurrOper);
2897 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2898 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2899 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2925 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2928 int64_t
Value = ConstOp1->getSExtValue();
2944 if (!
C.Op0.hasOneUse() ||
2951 unsigned NumBits =
Load->getMemoryVT().getSizeInBits();
2952 if ((NumBits != 8 && NumBits != 16) ||
2953 NumBits !=
Load->getMemoryVT().getStoreSizeInBits())
2959 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2962 uint64_t Mask = (1 << NumBits) - 1;
2965 int64_t SignedValue = ConstOp1->getSExtValue();
2972 }
else if (NumBits == 8) {
2998 if (
C.Op0.getValueType() != MVT::i32 ||
2999 Load->getExtensionType() != ExtType) {
3001 Load->getBasePtr(),
Load->getPointerInfo(),
3002 Load->getMemoryVT(),
Load->getAlign(),
3003 Load->getMemOperand()->getFlags());
3009 if (
C.Op1.getValueType() != MVT::i32 ||
3010 Value != ConstOp1->getZExtValue())
3020 if (
Load->getMemoryVT() == MVT::i8)
3023 switch (
Load->getExtensionType()) {
3041 if (
C.Op0.isMachineOpcode() &&
3042 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3046 if (
C.Op0.getValueType() == MVT::i128)
3048 if (
C.Op0.getValueType() == MVT::f128)
3060 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3089 unsigned Opcode0 =
C.Op0.getOpcode();
3096 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3111 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3112 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3134 if (C1 && C1->isZero()) {
3153 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3156 if (C1 && C1->getZExtValue() == 32) {
3157 SDValue ShlOp0 =
C.Op0.getOperand(0);
3176 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3179 C.Op1->getAsZExtVal() == 0) {
3181 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3182 C.Op0.getValueSizeInBits().getFixedValue()) {
3183 unsigned Type = L->getExtensionType();
3186 C.Op0 =
C.Op0.getOperand(0);
3202 if (
C.Opcode != SystemZISD::ICMP)
3212 if (!
C.Op1.isMachineOpcode() ||
3213 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3218 C.Opcode = SystemZISD::CMP_STACKGUARD;
3229 uint64_t Amount = Shift->getZExtValue();
3230 if (Amount >=
N.getValueSizeInBits())
3245 unsigned ICmpType) {
3246 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3268 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3274 if (EffectivelyUnsigned && CmpVal <
Low) {
3282 if (CmpVal == Mask) {
3288 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3294 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3302 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3308 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3337 if (
C.Op0.getValueType() == MVT::i128) {
3343 if (Mask && Mask->getAPIntValue() == 0) {
3344 C.Opcode = SystemZISD::VTM;
3361 uint64_t CmpVal = ConstOp1->getZExtValue();
3368 NewC.Op0 =
C.Op0.getOperand(0);
3369 NewC.Op1 =
C.Op0.getOperand(1);
3373 MaskVal = Mask->getZExtValue();
3393 MaskVal = -(CmpVal & -CmpVal);
3402 unsigned NewCCMask, ShiftVal;
3406 (MaskVal >> ShiftVal != 0) &&
3407 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3409 MaskVal >> ShiftVal,
3413 MaskVal >>= ShiftVal;
3417 (MaskVal << ShiftVal != 0) &&
3418 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3420 MaskVal << ShiftVal,
3424 MaskVal <<= ShiftVal;
3433 C.Opcode = SystemZISD::TM;
3435 if (Mask && Mask->getZExtValue() == MaskVal)
3440 C.CCMask = NewCCMask;
3446 if (
C.Opcode != SystemZISD::ICMP)
3448 if (
C.Op0.getValueType() != MVT::i128)
3459 Src = Src.getOperand(0);
3462 unsigned Opcode = 0;
3463 if (Src.hasOneUse()) {
3464 switch (Src.getOpcode()) {
3465 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3466 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3467 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3468 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3469 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3470 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3476 C.Op0 = Src->getOperand(0);
3477 C.Op1 = Src->getOperand(1);
3481 C.CCMask ^=
C.CCValid;
3493 C.Opcode = SystemZISD::VICMPES;
3505 bool Swap =
false, Invert =
false;
3517 C.Opcode = SystemZISD::UCMP128HI;
3519 C.Opcode = SystemZISD::SCMP128HI;
3524 C.CCMask ^=
C.CCValid;
3535 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3538 if ((~
Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3541 C.Op0 =
C.Op0.getOperand(0);
3553 C.CCValid = CCValid;
3556 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3559 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3563 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3566 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3570 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3573 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3576 C.CCMask &= CCValid;
3584 bool IsSignaling =
false) {
3587 unsigned Opcode, CCValid;
3599 Comparison
C(CmpOp0, CmpOp1, Chain);
3601 if (
C.Op0.getValueType().isFloatingPoint()) {
3604 C.Opcode = SystemZISD::FCMP;
3605 else if (!IsSignaling)
3606 C.Opcode = SystemZISD::STRICT_FCMP;
3608 C.Opcode = SystemZISD::STRICT_FCMPS;
3613 C.Opcode = SystemZISD::ICMP;
3649 if (!
C.Op1.getNode()) {
3650 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3651 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3653 switch (
C.Op0.getOpcode()) {
3664 if (
C.Opcode == SystemZISD::ICMP)
3665 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3667 if (
C.Opcode == SystemZISD::TM) {
3670 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3673 if (
C.Opcode == SystemZISD::VICMPES ||
3674 C.Opcode == SystemZISD::VICMPHS ||
3675 C.Opcode == SystemZISD::VICMPHLS ||
3676 C.Opcode == SystemZISD::VFCMPES ||
3677 C.Opcode == SystemZISD::VFCMPHS ||
3678 C.Opcode == SystemZISD::VFCMPHES) {
3679 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3686 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3688 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3697 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3698 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3723 unsigned CCValid,
unsigned CCMask) {
3728 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3806 int Mask[] = { Start, -1, Start + 1, -1 };
3810 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3812 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3826 !Subtarget.hasVectorEnhancements1()) {
3832 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3845 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3848 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3849 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3851 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3864 bool IsSignaling)
const {
3867 assert (!IsSignaling || Chain);
3870 bool Invert =
false;
3878 assert(IsFP &&
"Unexpected integer comparison");
3880 DL, VT, CmpOp1, CmpOp0, Chain);
3882 DL, VT, CmpOp0, CmpOp1, Chain);
3886 LT.getValue(1),
GE.getValue(1));
3895 assert(IsFP &&
"Unexpected integer comparison");
3897 DL, VT, CmpOp1, CmpOp0, Chain);
3899 DL, VT, CmpOp0, CmpOp1, Chain);
3903 LT.getValue(1),
GT.getValue(1));
3924 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3928 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3933 Chain =
Cmp.getValue(1);
3941 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3954 EVT VT =
Op.getValueType();
3956 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3965 bool IsSignaling)
const {
3971 EVT VT =
Op.getNode()->getValueType(0);
3973 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3974 Chain, IsSignaling);
3996 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4030 C.CCMask ^=
C.CCValid;
4038 Op = SystemZISD::VICMPE;
4042 Op = SystemZISD::VICMPHL;
4044 Op = SystemZISD::VICMPH;
4083 C.Op1->getAsZExtVal() == 0) {
4090 if (Subtarget.hasVectorEnhancements3() &&
4091 C.Opcode == SystemZISD::ICMP &&
4092 C.Op0.getValueType() == MVT::i128 &&
4102 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4108 const GlobalValue *GV =
Node->getGlobal();
4114 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4117 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4136 }
else if (Subtarget.isTargetELF()) {
4141 }
else if (Subtarget.isTargetzOS()) {
4172 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4177 Ops.push_back(Chain);
4179 Node->getValueType(0),
4188 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4189 const uint32_t *
Mask =
4191 assert(Mask &&
"Missing call preserved mask for calling convention");
4195 Ops.push_back(Glue);
4198 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4206SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4230 const GlobalValue *GV =
Node->getGlobal();
4238 SDValue TP = lowerThreadPointer(
DL, DAG);
4245 SystemZConstantPoolValue *CPV =
4254 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4260 SystemZConstantPoolValue *CPV =
4269 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4274 SystemZMachineFunctionInfo* MFI =
4303 SystemZConstantPoolValue *CPV =
4337 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4354 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4359 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4361 MachineFrameInfo &MFI = MF.getFrameInfo();
4365 unsigned Depth =
Op.getConstantOperandVal(0);
4372 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4377 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4383 MachinePointerInfo());
4398 unsigned Depth =
Op.getConstantOperandVal(0);
4403 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4406 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4407 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4408 int Offset = TFL->getReturnAddressOffset(MF);
4412 MachinePointerInfo());
4417 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4419 &SystemZ::GR64BitRegClass);
4427 EVT InVT =
In.getValueType();
4428 EVT ResVT =
Op.getValueType();
4436 LoadN->getBasePtr(), LoadN->getMemOperand());
4442 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4444 if (Subtarget.hasHighWord()) {
4448 MVT::i64,
SDValue(U64, 0), In);
4456 DL, MVT::f32, Out64);
4458 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4461 MVT::f64,
SDValue(U64, 0), In);
4463 if (Subtarget.hasHighWord())
4476 if (Subtarget.isTargetXPLINK64())
4477 return lowerVASTART_XPLINK(
Op, DAG);
4479 return lowerVASTART_ELF(
Op, DAG);
4485 SystemZMachineFunctionInfo *FuncInfo =
4486 MF.
getInfo<SystemZMachineFunctionInfo>();
4496 MachinePointerInfo(SV));
4502 SystemZMachineFunctionInfo *FuncInfo =
4503 MF.
getInfo<SystemZMachineFunctionInfo>();
4512 const unsigned NumFields = 4;
4523 for (
unsigned I = 0;
I < NumFields; ++
I) {
4528 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4529 MachinePointerInfo(SV,
Offset));
4549 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4550 MachinePointerInfo(SrcSV));
4554SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4556 if (Subtarget.isTargetXPLINK64())
4557 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4559 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4563SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4565 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4575 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4578 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4579 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4585 if (ExtraAlignSpace)
4589 bool IsSigned =
false;
4590 bool DoesNotReturn =
false;
4591 bool IsReturnValueUsed =
false;
4592 EVT VT =
Op.getValueType();
4602 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4614 if (ExtraAlignSpace) {
4626SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4628 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4631 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4640 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4643 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4644 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4655 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4656 MachinePointerInfo());
4659 if (ExtraAlignSpace)
4666 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4667 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4683 if (RequiredAlign > StackAlign) {
4693 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4694 MachinePointerInfo());
4700SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4704 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4709 unsigned Opcode)
const {
4710 EVT VT =
Op.getValueType();
4716 assert(Subtarget.hasMiscellaneousExtensions2());
4721 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4727 EVT VT =
Op.getValueType();
4735 else if (Subtarget.hasMiscellaneousExtensions2())
4740 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4775 EVT VT =
Op.getValueType();
4788 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4796 EVT VT =
Op.getValueType();
4816 EVT VT =
Op.getValueType();
4823 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4828 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4837 uint64_t Masks[] = {
Known[0].Zero.getZExtValue(),
4838 Known[1].Zero.getZExtValue() };
4840 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4842 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4879 MVT::i64, HighOp, Low32);
4885 SDNode *
N =
Op.getNode();
4890 if (
N->getValueType(0) == MVT::i128) {
4891 unsigned BaseOp = 0;
4892 unsigned FlagOp = 0;
4893 bool IsBorrow =
false;
4894 switch (
Op.getOpcode()) {
4898 FlagOp = SystemZISD::VACC;
4902 FlagOp = SystemZISD::VSCBI;
4917 unsigned BaseOp = 0;
4918 unsigned CCValid = 0;
4919 unsigned CCMask = 0;
4921 switch (
Op.getOpcode()) {
4924 BaseOp = SystemZISD::SADDO;
4929 BaseOp = SystemZISD::SSUBO;
4934 BaseOp = SystemZISD::UADDO;
4939 BaseOp = SystemZISD::USUBO;
4945 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4949 if (
N->getValueType(1) == MVT::i1)
4975 SDNode *
N =
Op.getNode();
4976 MVT VT =
N->getSimpleValueType(0);
4987 if (VT == MVT::i128) {
4988 unsigned BaseOp = 0;
4989 unsigned FlagOp = 0;
4990 bool IsBorrow =
false;
4991 switch (
Op.getOpcode()) {
4994 BaseOp = SystemZISD::VAC;
4995 FlagOp = SystemZISD::VACCC;
4998 BaseOp = SystemZISD::VSBI;
4999 FlagOp = SystemZISD::VSBCBI;
5018 unsigned BaseOp = 0;
5019 unsigned CCValid = 0;
5020 unsigned CCMask = 0;
5022 switch (
Op.getOpcode()) {
5028 BaseOp = SystemZISD::ADDCARRY;
5036 BaseOp = SystemZISD::SUBCARRY;
5047 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5051 if (
N->getValueType(1) == MVT::i1)
5059 EVT VT =
Op.getValueType();
5061 Op =
Op.getOperand(0);
5084 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5096 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5109 if (NumSignificantBits == 0)
5115 BitSize = std::min(BitSize, OrigBitSize);
5124 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5126 if (BitSize != OrigBitSize)
5163 EVT RegVT =
Op.getValueType();
5165 return lowerATOMIC_LDST_I128(
Op, DAG);
5166 return lowerLoadF16(
Op, DAG);
5172 if (
Node->getMemoryVT().getSizeInBits() == 128)
5173 return lowerATOMIC_LDST_I128(
Op, DAG);
5174 return lowerStoreF16(
Op, DAG);
5181 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5182 "Only custom lowering i128 or f128.");
5195 EVT WideVT = MVT::i32;
5218 unsigned Opcode)
const {
5222 EVT NarrowVT =
Node->getMemoryVT();
5223 EVT WideVT = MVT::i32;
5224 if (NarrowVT == WideVT)
5231 MachineMemOperand *MMO =
Node->getMemOperand();
5235 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5237 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5242 SDValue AlignedAddr, BitShift, NegBitShift;
5250 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5253 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5254 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5259 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5260 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5280 EVT MemVT =
Node->getMemoryVT();
5281 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5283 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5284 assert(Subtarget.hasInterlockedAccess1() &&
5285 "Should have been expanded by AtomicExpand pass.");
5291 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5292 Node->getMemOperand());
5295 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5306 MachineMemOperand *MMO =
Node->getMemOperand();
5309 if (
Node->getMemoryVT() == MVT::i128) {
5318 EVT NarrowVT =
Node->getMemoryVT();
5319 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5320 if (NarrowVT == WideVT) {
5321 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5322 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5324 DL, Tys,
Ops, NarrowVT, MMO);
5338 SDValue AlignedAddr, BitShift, NegBitShift;
5342 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5343 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5346 VTList,
Ops, NarrowVT, MMO);
5360SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5383 auto *Regs = Subtarget.getSpecialRegisters();
5386 "in GHC calling convention");
5388 Regs->getStackPointerRegister(),
Op.getValueType());
5394 auto *Regs = Subtarget.getSpecialRegisters();
5395 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5399 "in GHC calling convention");
5406 if (StoreBackchain) {
5408 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5409 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5410 MachinePointerInfo());
5413 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5416 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5417 MachinePointerInfo());
5424 bool IsData =
Op.getConstantOperandVal(4);
5427 return Op.getOperand(0);
5430 bool IsWrite =
Op.getConstantOperandVal(2);
5437 Node->getMemoryVT(),
Node->getMemOperand());
5441SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5443 unsigned Opcode, CCValid;
5445 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5456SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5458 unsigned Opcode, CCValid;
5461 if (
Op->getNumValues() == 1)
5463 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5468 unsigned Id =
Op.getConstantOperandVal(0);
5470 case Intrinsic::thread_pointer:
5471 return lowerThreadPointer(SDLoc(
Op), DAG);
5473 case Intrinsic::s390_vpdi:
5474 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5475 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5477 case Intrinsic::s390_vperm:
5478 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5479 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5481 case Intrinsic::s390_vuphb:
5482 case Intrinsic::s390_vuphh:
5483 case Intrinsic::s390_vuphf:
5484 case Intrinsic::s390_vuphg:
5485 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5488 case Intrinsic::s390_vuplhb:
5489 case Intrinsic::s390_vuplhh:
5490 case Intrinsic::s390_vuplhf:
5491 case Intrinsic::s390_vuplhg:
5492 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5495 case Intrinsic::s390_vuplb:
5496 case Intrinsic::s390_vuplhw:
5497 case Intrinsic::s390_vuplf:
5498 case Intrinsic::s390_vuplg:
5499 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5502 case Intrinsic::s390_vupllb:
5503 case Intrinsic::s390_vupllh:
5504 case Intrinsic::s390_vupllf:
5505 case Intrinsic::s390_vupllg:
5506 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5509 case Intrinsic::s390_vsumb:
5510 case Intrinsic::s390_vsumh:
5511 case Intrinsic::s390_vsumgh:
5512 case Intrinsic::s390_vsumgf:
5513 case Intrinsic::s390_vsumqf:
5514 case Intrinsic::s390_vsumqg:
5515 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5516 Op.getOperand(1),
Op.getOperand(2));
5518 case Intrinsic::s390_vaq:
5520 Op.getOperand(1),
Op.getOperand(2));
5521 case Intrinsic::s390_vaccb:
5522 case Intrinsic::s390_vacch:
5523 case Intrinsic::s390_vaccf:
5524 case Intrinsic::s390_vaccg:
5525 case Intrinsic::s390_vaccq:
5526 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5527 Op.getOperand(1),
Op.getOperand(2));
5528 case Intrinsic::s390_vacq:
5529 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5530 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5531 case Intrinsic::s390_vacccq:
5532 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5533 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5535 case Intrinsic::s390_vsq:
5537 Op.getOperand(1),
Op.getOperand(2));
5538 case Intrinsic::s390_vscbib:
5539 case Intrinsic::s390_vscbih:
5540 case Intrinsic::s390_vscbif:
5541 case Intrinsic::s390_vscbig:
5542 case Intrinsic::s390_vscbiq:
5543 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5544 Op.getOperand(1),
Op.getOperand(2));
5545 case Intrinsic::s390_vsbiq:
5546 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5547 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5548 case Intrinsic::s390_vsbcbiq:
5549 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5550 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5552 case Intrinsic::s390_vmhb:
5553 case Intrinsic::s390_vmhh:
5554 case Intrinsic::s390_vmhf:
5555 case Intrinsic::s390_vmhg:
5556 case Intrinsic::s390_vmhq:
5558 Op.getOperand(1),
Op.getOperand(2));
5559 case Intrinsic::s390_vmlhb:
5560 case Intrinsic::s390_vmlhh:
5561 case Intrinsic::s390_vmlhf:
5562 case Intrinsic::s390_vmlhg:
5563 case Intrinsic::s390_vmlhq:
5565 Op.getOperand(1),
Op.getOperand(2));
5567 case Intrinsic::s390_vmahb:
5568 case Intrinsic::s390_vmahh:
5569 case Intrinsic::s390_vmahf:
5570 case Intrinsic::s390_vmahg:
5571 case Intrinsic::s390_vmahq:
5572 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5573 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5574 case Intrinsic::s390_vmalhb:
5575 case Intrinsic::s390_vmalhh:
5576 case Intrinsic::s390_vmalhf:
5577 case Intrinsic::s390_vmalhg:
5578 case Intrinsic::s390_vmalhq:
5579 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5580 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5582 case Intrinsic::s390_vmeb:
5583 case Intrinsic::s390_vmeh:
5584 case Intrinsic::s390_vmef:
5585 case Intrinsic::s390_vmeg:
5586 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5587 Op.getOperand(1),
Op.getOperand(2));
5588 case Intrinsic::s390_vmleb:
5589 case Intrinsic::s390_vmleh:
5590 case Intrinsic::s390_vmlef:
5591 case Intrinsic::s390_vmleg:
5592 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5593 Op.getOperand(1),
Op.getOperand(2));
5594 case Intrinsic::s390_vmob:
5595 case Intrinsic::s390_vmoh:
5596 case Intrinsic::s390_vmof:
5597 case Intrinsic::s390_vmog:
5598 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5599 Op.getOperand(1),
Op.getOperand(2));
5600 case Intrinsic::s390_vmlob:
5601 case Intrinsic::s390_vmloh:
5602 case Intrinsic::s390_vmlof:
5603 case Intrinsic::s390_vmlog:
5604 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5605 Op.getOperand(1),
Op.getOperand(2));
5607 case Intrinsic::s390_vmaeb:
5608 case Intrinsic::s390_vmaeh:
5609 case Intrinsic::s390_vmaef:
5610 case Intrinsic::s390_vmaeg:
5612 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5613 Op.getOperand(1),
Op.getOperand(2)),
5615 case Intrinsic::s390_vmaleb:
5616 case Intrinsic::s390_vmaleh:
5617 case Intrinsic::s390_vmalef:
5618 case Intrinsic::s390_vmaleg:
5620 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5621 Op.getOperand(1),
Op.getOperand(2)),
5623 case Intrinsic::s390_vmaob:
5624 case Intrinsic::s390_vmaoh:
5625 case Intrinsic::s390_vmaof:
5626 case Intrinsic::s390_vmaog:
5628 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5629 Op.getOperand(1),
Op.getOperand(2)),
5631 case Intrinsic::s390_vmalob:
5632 case Intrinsic::s390_vmaloh:
5633 case Intrinsic::s390_vmalof:
5634 case Intrinsic::s390_vmalog:
5636 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5637 Op.getOperand(1),
Op.getOperand(2)),
5658 { SystemZISD::MERGE_HIGH, 8,
5659 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5661 { SystemZISD::MERGE_HIGH, 4,
5662 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5664 { SystemZISD::MERGE_HIGH, 2,
5665 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5667 { SystemZISD::MERGE_HIGH, 1,
5668 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5670 { SystemZISD::MERGE_LOW, 8,
5671 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5673 { SystemZISD::MERGE_LOW, 4,
5674 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5676 { SystemZISD::MERGE_LOW, 2,
5677 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5679 { SystemZISD::MERGE_LOW, 1,
5680 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5682 { SystemZISD::PACK, 4,
5683 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5685 { SystemZISD::PACK, 2,
5686 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5688 { SystemZISD::PACK, 1,
5689 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5691 { SystemZISD::PERMUTE_DWORDS, 4,
5692 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5694 { SystemZISD::PERMUTE_DWORDS, 1,
5695 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5709 OpNo0 = OpNo1 = OpNos[1];
5710 }
else if (OpNos[1] < 0) {
5711 OpNo0 = OpNo1 = OpNos[0];
5729 unsigned &OpNo0,
unsigned &OpNo1) {
5730 int OpNos[] = { -1, -1 };
5743 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5745 OpNos[ModelOpNo] = RealOpNo;
5753 unsigned &OpNo0,
unsigned &OpNo1) {
5770 int Elt = Bytes[From];
5773 Transform[From] = -1;
5775 while (
P.Bytes[To] != Elt) {
5780 Transform[From] = To;
5804 Bytes.
resize(NumElements * BytesPerElement, -1);
5805 for (
unsigned I = 0;
I < NumElements; ++
I) {
5806 int Index = VSN->getMaskElt(
I);
5808 for (
unsigned J = 0; J < BytesPerElement; ++J)
5809 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5813 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5816 Bytes.
resize(NumElements * BytesPerElement, -1);
5817 for (
unsigned I = 0;
I < NumElements; ++
I)
5818 for (
unsigned J = 0; J < BytesPerElement; ++J)
5819 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5830 unsigned BytesPerElement,
int &
Base) {
5832 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5833 if (Bytes[Start +
I] >= 0) {
5834 unsigned Elem = Bytes[Start +
I];
5838 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5840 }
else if (
unsigned(
Base) != Elem -
I)
5853 unsigned &StartIndex,
unsigned &OpNo0,
5855 int OpNos[] = { -1, -1 };
5857 for (
unsigned I = 0;
I < 16; ++
I) {
5858 int Index = Bytes[
I];
5864 Shift = ExpectedShift;
5865 else if (Shift != ExpectedShift)
5869 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5871 OpNos[ModelOpNo] = RealOpNo;
5884 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5885 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5893 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5895 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5896 }
else if (
P.Opcode == SystemZISD::PACK) {
5899 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5908 N =
N->getOperand(0);
5911 return Op->getZExtValue() == 0;
5917 for (
unsigned I = 0;
I < Num ;
I++)
5929 for (
unsigned I = 0;
I < 2; ++
I)
5933 unsigned StartIndex, OpNo0, OpNo1;
5935 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5942 if (ZeroVecIdx != UINT32_MAX) {
5943 bool MaskFirst =
true;
5948 if (OpNo == ZeroVecIdx &&
I == 0) {
5953 if (OpNo != ZeroVecIdx && Byte == 0) {
5960 if (ZeroIdx != -1) {
5963 if (Bytes[
I] >= 0) {
5966 if (OpNo == ZeroVecIdx)
5978 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5981 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5993 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5999struct GeneralShuffle {
6000 GeneralShuffle(EVT vt)
6001 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
6005 void tryPrepareForUnpack();
6006 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6021 unsigned UnpackFromEltSize;
6028void GeneralShuffle::addUndef() {
6030 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6031 Bytes.push_back(-1);
6040bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6046 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6051 if (FromBytesPerElement < BytesPerElement)
6055 (FromBytesPerElement - BytesPerElement));
6058 while (
Op.getNode()) {
6060 Op =
Op.getOperand(0);
6076 }
else if (
Op.isUndef()) {
6085 for (; OpNo <
Ops.size(); ++OpNo)
6086 if (
Ops[OpNo] ==
Op)
6088 if (OpNo ==
Ops.size())
6093 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6094 Bytes.push_back(
Base +
I);
6103 if (
Ops.size() == 0)
6107 tryPrepareForUnpack();
6110 if (
Ops.size() == 1)
6122 unsigned Stride = 1;
6123 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6124 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6134 else if (OpNo ==
I + Stride)
6145 if (NewBytes[J] >= 0) {
6147 "Invalid double permute");
6150 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6156 if (NewBytes[J] >= 0)
6172 unsigned OpNo0, OpNo1;
6176 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6181 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6188 dbgs() <<
Msg.c_str() <<
" { ";
6189 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6190 dbgs() << Bytes[
I] <<
" ";
6198void GeneralShuffle::tryPrepareForUnpack() {
6200 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6205 if (
Ops.size() > 2 &&
6210 UnpackFromEltSize = 1;
6211 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6212 bool MatchUnpack =
true;
6215 unsigned ToEltSize = UnpackFromEltSize * 2;
6216 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6219 if (Bytes[Elt] != -1) {
6221 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6222 MatchUnpack =
false;
6228 if (
Ops.size() == 2) {
6230 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6232 if (SrcBytes[i] == -1)
6234 if (SrcBytes[i] % 16 !=
int(i))
6235 CanUseUnpackHigh =
false;
6237 CanUseUnpackLow =
false;
6238 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6239 UnpackFromEltSize = UINT_MAX;
6243 if (!CanUseUnpackHigh)
6249 if (UnpackFromEltSize > 4)
6252 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6253 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6255 dumpBytes(Bytes,
"Original Bytes vector:"););
6264 Elt += UnpackFromEltSize;
6265 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6266 Bytes[
B] = Bytes[Elt];
6274 Ops.erase(&
Ops[ZeroVecOpNo]);
6276 if (Bytes[
I] >= 0) {
6278 if (OpNo > ZeroVecOpNo)
6289 if (!unpackWasPrepared())
6291 unsigned InBits = UnpackFromEltSize * 8;
6295 unsigned OutBits = InBits * 2;
6298 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6299 : SystemZISD::UNPACKL_HIGH,
6300 DL, OutVT, PackedOp);
6305 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6306 if (!
Op.getOperand(
I).isUndef())
6322 if (
Value.isUndef())
6334 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6337 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6338 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6359 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6375 GeneralShuffle GS(VT);
6377 bool FoundOne =
false;
6378 for (
unsigned I = 0;
I < NumElements; ++
I) {
6381 Op =
Op.getOperand(0);
6384 unsigned Elem =
Op.getConstantOperandVal(1);
6385 if (!GS.add(
Op.getOperand(0), Elem))
6388 }
else if (
Op.isUndef()) {
6402 if (!ResidueOps.
empty()) {
6403 while (ResidueOps.
size() < NumElements)
6405 for (
auto &
Op : GS.Ops) {
6406 if (!
Op.getNode()) {
6412 return GS.getNode(DAG,
SDLoc(BVN));
6415bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6421 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6432 "Handling full vectors only.");
6452 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6464 unsigned int NumElements = Elems.
size();
6465 unsigned int Count = 0;
6466 for (
auto Elem : Elems) {
6467 if (!Elem.isUndef()) {
6470 else if (Elem != Single) {
6490 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6491 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6494 bool AllLoads =
true;
6495 for (
auto Elem : Elems)
6496 if (!isVectorElementLoad(Elem)) {
6502 if (VT == MVT::v2i64 && !AllLoads)
6506 if (VT == MVT::v2f64 && !AllLoads)
6516 if (VT == MVT::v4f32 && !AllLoads)
6520 if (VT == MVT::v8f16 && !AllLoads) {
6529 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6538 unsigned NumConstants = 0;
6539 for (
unsigned I = 0;
I < NumElements; ++
I) {
6553 if (NumConstants > 0) {
6554 for (
unsigned I = 0;
I < NumElements; ++
I)
6565 std::map<const SDNode*, unsigned> UseCounts;
6566 SDNode *LoadMaxUses =
nullptr;
6567 for (
unsigned I = 0;
I < NumElements; ++
I)
6568 if (isVectorElementLoad(Elems[
I])) {
6569 SDNode *Ld = Elems[
I].getNode();
6570 unsigned Count = ++UseCounts[Ld];
6571 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6574 if (LoadMaxUses !=
nullptr) {
6575 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6579 unsigned I1 = NumElements / 2 - 1;
6580 unsigned I2 = NumElements - 1;
6581 bool Def1 = !Elems[
I1].isUndef();
6582 bool Def2 = !Elems[I2].isUndef();
6596 for (
unsigned I = 0;
I < NumElements; ++
I)
6597 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6607 EVT VT =
Op.getValueType();
6609 if (BVN->isConstant()) {
6610 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6628 for (
unsigned I = 0;
I < NumElements; ++
I)
6630 return buildVector(DAG,
DL, VT,
Ops);
6637 EVT VT =
Op.getValueType();
6640 if (VSN->isSplat()) {
6642 unsigned Index = VSN->getSplatIndex();
6644 "Splat index should be defined and in first operand");
6650 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6654 GeneralShuffle
GS(VT);
6655 for (
unsigned I = 0;
I < NumElements; ++
I) {
6656 int Elt = VSN->getMaskElt(
I);
6659 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6660 unsigned(Elt) % NumElements))
6663 return GS.getNode(DAG, SDLoc(VSN));
6678 assert(
Op.getSimpleValueType() == MVT::i64 &&
6679 "Expexted to convert i64 to f16.");
6691 assert(
Op.getSimpleValueType() == MVT::f16 &&
6692 "Expected to convert f16 to i64.");
6709 EVT VT =
Op.getValueType();
6714 if (VT == MVT::v2f64 &&
6738SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6744 EVT VT =
Op.getValueType();
6749 uint64_t
Index = CIndexN->getZExtValue();
6758 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6766SDValue SystemZTargetLowering::
6769 EVT OutVT =
Op.getValueType();
6773 unsigned StartOffset = 0;
6780 ArrayRef<int> ShuffleMask = SVN->
getMask();
6785 if (ToBits == 64 && OutNumElts == 2) {
6786 int NumElem = ToBits / FromBits;
6787 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6793 int StartOffsetCandidate = -1;
6794 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6795 if (ShuffleMask[Elt] == -1)
6797 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6798 if (StartOffsetCandidate == -1)
6799 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6800 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6803 StartOffsetCandidate = -1;
6806 if (StartOffsetCandidate != -1) {
6807 StartOffset = StartOffsetCandidate;
6816 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6817 if (StartOffset >= OutNumElts) {
6818 Opcode = SystemZISD::UNPACK_LOW;
6819 StartOffset -= OutNumElts;
6821 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6822 }
while (FromBits != ToBits);
6827SDValue SystemZTargetLowering::
6831 EVT OutVT =
Op.getValueType();
6835 unsigned NumInPerOut = InNumElts / OutNumElts;
6840 SmallVector<int, 16>
Mask(InNumElts);
6841 unsigned ZeroVecElt = InNumElts;
6842 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6843 unsigned MaskElt = PackedElt * NumInPerOut;
6844 unsigned End = MaskElt + NumInPerOut - 1;
6845 for (; MaskElt < End; MaskElt++)
6846 Mask[MaskElt] = ZeroVecElt++;
6847 Mask[MaskElt] = PackedElt;
6854 unsigned ByScalar)
const {
6859 EVT VT =
Op.getValueType();
6864 APInt SplatBits, SplatUndef;
6865 unsigned SplatBitSize;
6869 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6870 ElemBitSize,
true) &&
6871 SplatBitSize == ElemBitSize) {
6874 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6877 BitVector UndefElements;
6883 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6890 if (VSN->isSplat()) {
6891 SDValue VSNOp0 = VSN->getOperand(0);
6892 unsigned Index = VSN->getSplatIndex();
6894 "Splat index should be defined and in first operand");
6901 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6919 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6920 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6923 if (ShiftAmt > 120) {
6927 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6931 SmallVector<int, 16>
Mask(16);
6932 for (
unsigned Elt = 0; Elt < 16; Elt++)
6933 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6935 if ((ShiftAmt & 7) == 0)
6939 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6957 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6958 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6961 if (ShiftAmt > 120) {
6965 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6969 SmallVector<int, 16>
Mask(16);
6970 for (
unsigned Elt = 0; Elt < 16; Elt++)
6971 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6973 if ((ShiftAmt & 7) == 0)
6977 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6989 MVT DstVT =
Op.getSimpleValueType();
6992 unsigned SrcAS =
N->getSrcAddressSpace();
6994 assert(SrcAS !=
N->getDestAddressSpace() &&
6995 "addrspacecast must be between different address spaces");
7003 }
else if (DstVT == MVT::i32) {
7017 if (
In.getSimpleValueType() != MVT::f16)
7024 SDValue Chain,
bool IsStrict)
const {
7025 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7028 std::tie(Result, Chain) =
7037 bool IsStrict =
Op->isStrictFPOpcode();
7039 MVT VT =
Op.getSimpleValueType();
7040 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7048 if (!Subtarget.hasFPExtension() && !IsSigned)
7059 if (VT == MVT::i128) {
7062 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7072 bool IsStrict =
Op->isStrictFPOpcode();
7074 MVT VT =
Op.getSimpleValueType();
7075 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7080 if (VT == MVT::f16) {
7087 if (!Subtarget.hasFPExtension() && !IsSigned)
7090 if (InVT == MVT::i128) {
7093 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7102 EVT RegVT =
Op.getValueType();
7103 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7110 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7112 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7113 AtomicLd->getMemOperand());
7133 Shft, AtomicSt->getBasePtr(),
7134 AtomicSt->getMemOperand());
7144 MVT ResultVT =
Op.getSimpleValueType();
7146 unsigned Check =
Op.getConstantOperandVal(1);
7148 unsigned TDCMask = 0;
7183 MachinePointerInfo MPI =
7189 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7193 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7198 switch (
Op.getOpcode()) {
7200 return lowerFRAMEADDR(
Op, DAG);
7202 return lowerRETURNADDR(
Op, DAG);
7204 return lowerBR_CC(
Op, DAG);
7206 return lowerSELECT_CC(
Op, DAG);
7208 return lowerSETCC(
Op, DAG);
7210 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7212 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7224 return lowerBITCAST(
Op, DAG);
7226 return lowerVASTART(
Op, DAG);
7228 return lowerVACOPY(
Op, DAG);
7230 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7232 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7234 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7236 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7238 return lowerSMUL_LOHI(
Op, DAG);
7240 return lowerUMUL_LOHI(
Op, DAG);
7242 return lowerSDIVREM(
Op, DAG);
7244 return lowerUDIVREM(
Op, DAG);
7249 return lowerXALUO(
Op, DAG);
7252 return lowerUADDSUBO_CARRY(
Op, DAG);
7254 return lowerOR(
Op, DAG);
7256 return lowerCTPOP(
Op, DAG);
7258 return lowerVECREDUCE_ADD(
Op, DAG);
7260 return lowerATOMIC_FENCE(
Op, DAG);
7262 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7264 return lowerATOMIC_STORE(
Op, DAG);
7266 return lowerATOMIC_LOAD(
Op, DAG);
7268 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7270 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7272 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7274 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7276 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7278 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7280 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7282 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7284 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7286 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7288 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7290 return lowerSTACKSAVE(
Op, DAG);
7292 return lowerSTACKRESTORE(
Op, DAG);
7294 return lowerPREFETCH(
Op, DAG);
7296 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7298 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7300 return lowerBUILD_VECTOR(
Op, DAG);
7302 return lowerVECTOR_SHUFFLE(
Op, DAG);
7304 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7306 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7308 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7310 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7312 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7314 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7316 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7318 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7322 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7324 return lowerFSHL(
Op, DAG);
7326 return lowerFSHR(
Op, DAG);
7329 return lowerFP_EXTEND(
Op, DAG);
7334 return lower_FP_TO_INT(
Op, DAG);
7339 return lower_INT_TO_FP(
Op, DAG);
7341 return lowerLoadF16(
Op, DAG);
7343 return lowerStoreF16(
Op, DAG);
7345 return lowerIS_FPCLASS(
Op, DAG);
7347 return lowerGET_ROUNDING(
Op, DAG);
7349 return lowerREADCYCLECOUNTER(
Op, DAG);
7371 &SystemZ::FP128BitRegClass);
7380 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7395 &SystemZ::FP128BitRegClass);
7412 switch (
N->getOpcode()) {
7416 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7419 DL, Tys,
Ops, MVT::i128, MMO);
7422 if (
N->getValueType(0) == MVT::f128)
7436 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7439 DL, Tys,
Ops, MVT::i128, MMO);
7445 MVT::Other, Res), 0);
7457 DL, Tys,
Ops, MVT::i128, MMO);
7471 EVT SrcVT = Src.getValueType();
7472 EVT ResVT =
N->getValueType(0);
7473 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7475 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7476 if (Subtarget.hasVector()) {
7484 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7486 Subtarget.hasVector()
7500 bool IsStrict =
N->isStrictFPOpcode();
7502 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7503 EVT ResVT =
N->getValueType(0);
7505 if (ResVT == MVT::f16) {
7528 bool IsStrict =
N->isStrictFPOpcode();
7530 EVT ResVT =
N->getValueType(0);
7531 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7534 if (InVT == MVT::f16) {
7540 std::tie(InF32, Chain) =
7565bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7566 if (!Subtarget.hasVector())
7580 DAGCombinerInfo &DCI,
7588 unsigned Opcode =
Op.getOpcode();
7591 Op =
Op.getOperand(0);
7593 canTreatAsByteVector(
Op.getValueType())) {
7602 BytesPerElement,
First))
7609 if (Byte % BytesPerElement != 0)
7612 Index = Byte / BytesPerElement;
7616 canTreatAsByteVector(
Op.getValueType())) {
7619 EVT OpVT =
Op.getValueType();
7621 if (OpBytesPerElement < BytesPerElement)
7625 unsigned End = (
Index + 1) * BytesPerElement;
7626 if (End % OpBytesPerElement != 0)
7629 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7630 if (!
Op.getValueType().isInteger()) {
7633 DCI.AddToWorklist(
Op.getNode());
7638 DCI.AddToWorklist(
Op.getNode());
7645 canTreatAsByteVector(
Op.getValueType()) &&
7646 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7648 EVT ExtVT =
Op.getValueType();
7649 EVT OpVT =
Op.getOperand(0).getValueType();
7652 unsigned Byte =
Index * BytesPerElement;
7653 unsigned SubByte =
Byte % ExtBytesPerElement;
7654 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7655 if (SubByte < MinSubByte ||
7656 SubByte + BytesPerElement > ExtBytesPerElement)
7659 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7661 Byte += SubByte - MinSubByte;
7662 if (Byte % BytesPerElement != 0)
7664 Op =
Op.getOperand(0);
7671 if (
Op.getValueType() != VecVT) {
7673 DCI.AddToWorklist(
Op.getNode());
7683SDValue SystemZTargetLowering::combineTruncateExtract(
7692 if (canTreatAsByteVector(VecVT)) {
7696 if (BytesPerElement % TruncBytes == 0) {
7702 unsigned Scale = BytesPerElement / TruncBytes;
7703 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7710 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7711 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7719SDValue SystemZTargetLowering::combineZERO_EXTEND(
7720 SDNode *
N, DAGCombinerInfo &DCI)
const {
7722 SelectionDAG &DAG = DCI.DAG;
7724 EVT VT =
N->getValueType(0);
7725 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7728 if (TrueOp && FalseOp) {
7738 DCI.CombineTo(N0.
getNode(), TruncSelect);
7781 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7799SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7800 SDNode *
N, DAGCombinerInfo &DCI)
const {
7804 SelectionDAG &DAG = DCI.DAG;
7806 EVT VT =
N->getValueType(0);
7820SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7821 SDNode *
N, DAGCombinerInfo &DCI)
const {
7825 SelectionDAG &DAG = DCI.DAG;
7827 EVT VT =
N->getValueType(0);
7834 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7835 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7851SDValue SystemZTargetLowering::combineMERGE(
7852 SDNode *
N, DAGCombinerInfo &DCI)
const {
7853 SelectionDAG &DAG = DCI.DAG;
7854 unsigned Opcode =
N->getOpcode();
7862 if (Op1 ==
N->getOperand(0))
7867 if (ElemBytes <= 4) {
7868 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7869 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7875 DCI.AddToWorklist(Op1.
getNode());
7878 DCI.AddToWorklist(
Op.getNode());
7887 LoPart = HiPart =
nullptr;
7892 if (
Use.getResNo() != 0)
7897 bool IsLoPart =
true;
7922 LoPart = HiPart =
nullptr;
7927 if (
Use.getResNo() != 0)
7933 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7936 switch (
User->getConstantOperandVal(1)) {
7937 case SystemZ::subreg_l64:
7942 case SystemZ::subreg_h64:
7954SDValue SystemZTargetLowering::combineLOAD(
7955 SDNode *
N, DAGCombinerInfo &DCI)
const {
7956 SelectionDAG &DAG = DCI.DAG;
7957 EVT LdVT =
N->getValueType(0);
7961 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7962 if (PtrVT != LoadNodeVT) {
7966 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7967 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7968 LN->getMemOperand());
7978 SDNode *LoPart, *HiPart;
7986 LD->getPointerInfo(),
LD->getBaseAlign(),
7987 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7989 DCI.CombineTo(HiPart, EltLoad,
true);
7996 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7997 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7999 DCI.CombineTo(LoPart, EltLoad,
true);
8006 DCI.AddToWorklist(Chain.
getNode());
8021 for (SDUse &Use :
N->uses()) {
8022 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8026 }
else if (
Use.getResNo() == 0)
8029 if (!Replicate || OtherUses.
empty())
8035 for (SDNode *U : OtherUses) {
8038 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8044bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8045 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8047 if (Subtarget.hasVectorEnhancements2())
8048 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8060 for (
unsigned i = 0; i < NumElts; ++i) {
8061 if (M[i] < 0)
continue;
8062 if ((
unsigned) M[i] != NumElts - 1 - i)
8070 for (
auto *U : StoredVal->
users()) {
8072 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8131SDValue SystemZTargetLowering::combineSTORE(
8132 SDNode *
N, DAGCombinerInfo &DCI)
const {
8133 SelectionDAG &DAG = DCI.DAG;
8136 EVT MemVT = SN->getMemoryVT();
8140 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8141 if (PtrVT != StoreNodeVT) {
8145 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8146 SN->getPointerInfo(), SN->getBaseAlign(),
8147 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8155 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8157 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8158 DCI.AddToWorklist(
Value.getNode());
8162 SN->getBasePtr(), SN->getMemoryVT(),
8163 SN->getMemOperand());
8174 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8178 if (!SN->isTruncatingStore() &&
8194 Ops, MemVT, SN->getMemOperand());
8197 if (!SN->isTruncatingStore() &&
8200 Subtarget.hasVectorEnhancements2()) {
8202 ArrayRef<int> ShuffleMask = SVN->
getMask();
8210 Ops, MemVT, SN->getMemOperand());
8215 if (!SN->isTruncatingStore() &&
8218 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8222 Ops, MemVT, SN->getMemOperand());
8232 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8233 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8235 SN->getChain(),
DL, LoPart,
8237 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8238 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8256 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8258 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8262 APInt Val =
C->getAPIntValue();
8265 assert(SN->isTruncatingStore() &&
8266 "Non-truncating store and immediate value does not fit?");
8267 Val = Val.
trunc(TotBytes * 8);
8270 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8271 if (VCI.isVectorConstantLegal(Subtarget) &&
8272 VCI.Opcode == SystemZISD::REPLICATE) {
8280 auto FindReplicatedReg = [&](
SDValue MulOp) {
8281 EVT MulVT = MulOp.getValueType();
8282 if (MulOp->getOpcode() ==
ISD::MUL &&
8283 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8287 WordVT =
LHS->getOperand(0).getValueType();
8294 SystemZVectorConstantInfo VCI(
8296 if (VCI.isVectorConstantLegal(Subtarget) &&
8297 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8298 WordVT == VCI.VecVT.getScalarType())
8310 FindReplicatedReg(SplatVal);
8315 FindReplicatedReg(Op1);
8320 "Bad type handling");
8324 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8325 SN->getBasePtr(), SN->getMemOperand());
8332SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8333 SDNode *
N, DAGCombinerInfo &DCI)
const {
8334 SelectionDAG &DAG = DCI.DAG;
8337 N->getOperand(0).hasOneUse() &&
8338 Subtarget.hasVectorEnhancements2()) {
8340 ArrayRef<int> ShuffleMask = SVN->
getMask();
8353 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8357 DCI.CombineTo(
N, ESLoad);
8361 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8371SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8372 SDNode *
N, DAGCombinerInfo &DCI)
const {
8373 SelectionDAG &DAG = DCI.DAG;
8375 if (!Subtarget.hasVector())
8381 Op.getValueType().isVector() &&
8382 Op.getOperand(0).getValueType().isVector() &&
8383 Op.getValueType().getVectorNumElements() ==
8384 Op.getOperand(0).getValueType().getVectorNumElements())
8385 Op =
Op.getOperand(0);
8389 EVT VecVT =
Op.getValueType();
8392 Op.getOperand(0),
N->getOperand(1));
8393 DCI.AddToWorklist(
Op.getNode());
8395 if (EltVT !=
N->getValueType(0)) {
8396 DCI.AddToWorklist(
Op.getNode());
8406 if (canTreatAsByteVector(VecVT))
8407 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8408 IndexN->getZExtValue(), DCI,
false);
8413SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8414 SDNode *
N, DAGCombinerInfo &DCI)
const {
8415 SelectionDAG &DAG = DCI.DAG;
8417 if (
N->getOperand(0) ==
N->getOperand(1))
8418 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8428 if (Chain1 == Chain2)
8436SDValue SystemZTargetLowering::combineFP_ROUND(
8437 SDNode *
N, DAGCombinerInfo &DCI)
const {
8439 if (!Subtarget.hasVector())
8448 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8449 SelectionDAG &DAG = DCI.DAG;
8451 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8457 for (
auto *U : Vec->
users()) {
8458 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8460 U->getOperand(0) == Vec &&
8462 U->getConstantOperandVal(1) == 1) {
8464 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8468 if (
N->isStrictFPOpcode()) {
8472 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8473 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8476 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8478 DCI.AddToWorklist(VRound.
getNode());
8482 DCI.AddToWorklist(Extract1.
getNode());
8488 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8491 N->getVTList(), Extract0, Chain);
8500SDValue SystemZTargetLowering::combineFP_EXTEND(
8501 SDNode *
N, DAGCombinerInfo &DCI)
const {
8503 if (!Subtarget.hasVector())
8512 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8513 SelectionDAG &DAG = DCI.DAG;
8515 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8521 for (
auto *U : Vec->
users()) {
8522 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8524 U->getOperand(0) == Vec &&
8526 U->getConstantOperandVal(1) == 2) {
8528 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8532 if (
N->isStrictFPOpcode()) {
8536 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8537 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8540 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8542 DCI.AddToWorklist(VExtend.
getNode());
8546 DCI.AddToWorklist(Extract1.
getNode());
8552 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8555 N->getVTList(), Extract0, Chain);
8564SDValue SystemZTargetLowering::combineINT_TO_FP(
8565 SDNode *
N, DAGCombinerInfo &DCI)
const {
8568 SelectionDAG &DAG = DCI.DAG;
8570 unsigned Opcode =
N->getOpcode();
8571 EVT OutVT =
N->getValueType(0);
8575 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8581 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8582 OutScalarBits <= 64) {
8586 unsigned ExtOpcode =
8589 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8594SDValue SystemZTargetLowering::combineFCOPYSIGN(
8595 SDNode *
N, DAGCombinerInfo &DCI)
const {
8596 SelectionDAG &DAG = DCI.DAG;
8597 EVT VT =
N->getValueType(0);
8610SDValue SystemZTargetLowering::combineBSWAP(
8611 SDNode *
N, DAGCombinerInfo &DCI)
const {
8612 SelectionDAG &DAG = DCI.DAG;
8615 N->getOperand(0).hasOneUse() &&
8616 canLoadStoreByteSwapped(
N->getValueType(0))) {
8625 EVT LoadVT =
N->getValueType(0);
8626 if (LoadVT == MVT::i16)
8631 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8635 if (
N->getValueType(0) == MVT::i16)
8640 DCI.CombineTo(
N, ResVal);
8644 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8653 Op.getValueType().isVector() &&
8654 Op.getOperand(0).getValueType().isVector() &&
8655 Op.getValueType().getVectorNumElements() ==
8656 Op.getOperand(0).getValueType().getVectorNumElements())
8657 Op =
Op.getOperand(0);
8669 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8671 EVT VecVT =
N->getValueType(0);
8675 DCI.AddToWorklist(Vec.
getNode());
8679 DCI.AddToWorklist(Elt.
getNode());
8682 DCI.AddToWorklist(Vec.
getNode());
8684 DCI.AddToWorklist(Elt.
getNode());
8692 if (SV &&
Op.hasOneUse()) {
8700 EVT VecVT =
N->getValueType(0);
8703 DCI.AddToWorklist(Op0.
getNode());
8707 DCI.AddToWorklist(Op1.
getNode());
8710 DCI.AddToWorklist(Op0.
getNode());
8712 DCI.AddToWorklist(Op1.
getNode());
8720SDValue SystemZTargetLowering::combineSETCC(
8721 SDNode *
N, DAGCombinerInfo &DCI)
const {
8722 SelectionDAG &DAG = DCI.DAG;
8728 EVT VT =
N->getValueType(0);
8738 Src.getValueType().isFixedLengthVector() &&
8739 Src.getValueType().getScalarType() == MVT::i1) {
8740 EVT CmpVT = Src.getOperand(0).getValueType();
8757 unsigned Depth = 0) {
8765 case SystemZISD::IPM:
8770 case SystemZISD::SELECT_CCMASK: {
8772 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8773 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8776 return std::make_pair(OpCC, OpCCValid);
8781 int CCValidVal = CCValid->getZExtValue();
8782 return std::make_pair(Op4CCReg, CCValidVal);
8793 return std::make_pair(Op0CC, Op0CCValid);
8809 return {Val, Val, Val, Val};
8810 case SystemZISD::IPM: {
8815 for (
auto CC : {0, 1, 2, 3})
8818 return ShiftedCCVals;
8820 case SystemZISD::SELECT_CCMASK: {
8824 if (!CCValid || !CCMask)
8827 int CCValidVal = CCValid->getZExtValue();
8828 int CCMaskVal = CCMask->getZExtValue();
8838 if (TrueSDVals.empty() || FalseSDVals.empty())
8841 for (
auto &CCVal : {0, 1, 2, 3})
8842 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8844 : FalseSDVals[CCVal]);
8845 return MergedSDVals;
8862 if (Op0SDVals.empty() || Op1SDVals.empty())
8865 for (
auto CCVal : {0, 1, 2, 3})
8867 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8868 return BinaryOpSDVals;
8879 auto *CCNode = CCReg.
getNode();
8883 if (CCNode->getOpcode() == SystemZISD::TM) {
8886 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8889 if (!Op0Node || !Op1Node)
8891 auto Op0APVal = Op0Node->getAPIntValue();
8892 auto Op1APVal = Op1Node->getAPIntValue();
8893 auto Result = Op0APVal & Op1APVal;
8894 bool AllOnes = Result == Op1APVal;
8895 bool AllZeros = Result == 0;
8896 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
8897 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8901 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8906 if (Op0SDVals.empty() || Op1SDVals.empty())
8909 for (
auto CC : {0, 1, 2, 3}) {
8910 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8914 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8916 NewCCMask &= Op0CCValid;
8919 CCValid = Op0CCValid;
8922 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8929 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8933 if (Op0SDVals.empty() || Op1SDVals.empty())
8937 auto CmpTypeVal = CmpType->getZExtValue();
8938 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8942 if (!Op0Node || !Op1Node)
8944 auto Op0APVal = Op0Node->getAPIntValue();
8945 auto Op1APVal = Op1Node->getAPIntValue();
8947 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8948 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8951 for (
auto CC : {0, 1, 2, 3}) {
8952 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8956 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8958 NewCCMask &= Op0CCValid;
8961 CCValid = Op0CCValid;
8974 const auto isFlagOutOpCC = [](
const Value *V) {
8976 const Value *RHSVal;
8983 if (CB->isInlineAsm()) {
8985 return IA && IA->getConstraintString().contains(
"{@cc}");
8996 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8999 return {-1, -1, -1};
9003 DAGCombinerInfo &DCI)
const {
9009 if (!CCValid || !CCMask)
9012 int CCValidVal = CCValid->getZExtValue();
9013 int CCMaskVal = CCMask->getZExtValue();
9020 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9021 CCMaskVal != CCValidVal)
9022 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9026 N->getOperand(3), CCReg);
9030SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9031 SDNode *
N, DAGCombinerInfo &DCI)
const {
9037 if (!CCValid || !CCMask)
9040 int CCValidVal = CCValid->getZExtValue();
9041 int CCMaskVal = CCMask->getZExtValue();
9044 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9048 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9049 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9051 if (Val.getOperand(4) != CCReg)
9058 int CCMaskVal = CCMask->getZExtValue();
9059 for (
auto &CC : {0, 1, 2, 3})
9060 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9074 if (TrueSDVals.empty())
9075 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9076 if (FalseSDVals.empty())
9077 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9078 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9079 SmallSet<SDValue, 4> MergedSDValsSet;
9081 for (
auto CC : {0, 1, 2, 3}) {
9082 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9083 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9087 if (MergedSDValsSet.
size() == 1)
9088 return *MergedSDValsSet.
begin();
9089 if (MergedSDValsSet.
size() == 2) {
9090 auto BeginIt = MergedSDValsSet.
begin();
9091 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9092 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9095 for (
auto CC : {0, 1, 2, 3}) {
9097 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9098 ? (TrueSDVals[CC] == NewTrueVal)
9099 : (FalseSDVals[CC] == NewTrueVal);
9101 CCMaskVal = NewCCMask;
9102 CCMaskVal &= CCValidVal;
9105 IsCombinedCCReg =
true;
9113 if (CCMaskVal == CCValidVal)
9116 if (IsCombinedCCReg)
9118 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9125SDValue SystemZTargetLowering::combineGET_CCMASK(
9126 SDNode *
N, DAGCombinerInfo &DCI)
const {
9131 if (!CCValid || !CCMask)
9133 int CCValidVal = CCValid->getZExtValue();
9134 int CCMaskVal = CCMask->getZExtValue();
9139 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9144 if (!SelectCCValid || !SelectCCMask)
9146 int SelectCCValidVal = SelectCCValid->getZExtValue();
9147 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9151 if (!TrueVal || !FalseVal)
9155 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9156 SelectCCMaskVal ^= SelectCCValidVal;
9160 if (SelectCCValidVal & ~CCValidVal)
9162 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9165 return Select->getOperand(4);
9168SDValue SystemZTargetLowering::combineIntDIVREM(
9169 SDNode *
N, DAGCombinerInfo &DCI)
const {
9170 SelectionDAG &DAG = DCI.DAG;
9171 EVT VT =
N->getValueType(0);
9188SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9189 SDNode *
N, DAGCombinerInfo &DCI)
const {
9190 SelectionDAG &DAG = DCI.DAG;
9194 "SRL or SRA node is required here!");
9196 if (!Subtarget.hasVector())
9206 SDValue ShiftOperand =
N->getOperand(0);
9226 if (!IsSignExt && !IsZeroExt)
9234 unsigned ActiveBits = IsSignExt
9235 ?
Constant->getAPIntValue().getSignificantBits()
9236 :
Constant->getAPIntValue().getActiveBits();
9237 if (ActiveBits > NarrowVTSize)
9253 unsigned ActiveBits = IsSignExt
9254 ?
Constant->getAPIntValue().getSignificantBits()
9255 :
Constant->getAPIntValue().getActiveBits();
9256 if (ActiveBits > NarrowVTSize)
9273 "Cannot have a multiply node with two different operand types.");
9275 "Cannot have an add node with two different operand types.");
9286 if (ShiftAmt != NarrowVTSize)
9290 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9291 NarrowVT == MVT::v4i32 ||
9292 (Subtarget.hasVectorEnhancements3() &&
9293 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9299 MulhRightOp, MulhAddOp);
9300 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9311 EVT VT =
Op.getValueType();
9320 Op =
Op.getOperand(0);
9321 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9325 bool CanUseEven =
true, CanUseOdd =
true;
9326 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9327 if (ShuffleMask[Elt] == -1)
9329 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9331 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9334 Op =
Op.getOperand(0);
9336 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9338 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9344 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9348 Op =
Op.getOperand(0);
9350 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9352 unsigned Elem =
Op.getConstantOperandVal(1);
9353 Op =
Op.getOperand(0);
9355 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9357 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9364SDValue SystemZTargetLowering::combineMUL(
9365 SDNode *
N, DAGCombinerInfo &DCI)
const {
9366 SelectionDAG &DAG = DCI.DAG;
9373 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9374 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9379SDValue SystemZTargetLowering::combineINTRINSIC(
9380 SDNode *
N, DAGCombinerInfo &DCI)
const {
9381 SelectionDAG &DAG = DCI.DAG;
9383 unsigned Id =
N->getConstantOperandVal(1);
9387 case Intrinsic::s390_vll:
9388 case Intrinsic::s390_vlrl:
9390 if (
C->getZExtValue() >= 15)
9391 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9392 N->getOperand(3), MachinePointerInfo());
9395 case Intrinsic::s390_vstl:
9396 case Intrinsic::s390_vstrl:
9398 if (
C->getZExtValue() >= 15)
9399 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9400 N->getOperand(4), MachinePointerInfo());
9408 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9415 switch(
N->getOpcode()) {
9420 case SystemZISD::MERGE_HIGH:
9421 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9426 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9436 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9437 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9440 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9441 case ISD::MUL:
return combineMUL(
N, DCI);
9445 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9457 EVT VT =
Op.getValueType();
9460 unsigned Opcode =
Op.getOpcode();
9462 unsigned Id =
Op.getConstantOperandVal(0);
9464 case Intrinsic::s390_vpksh:
9465 case Intrinsic::s390_vpksf:
9466 case Intrinsic::s390_vpksg:
9467 case Intrinsic::s390_vpkshs:
9468 case Intrinsic::s390_vpksfs:
9469 case Intrinsic::s390_vpksgs:
9470 case Intrinsic::s390_vpklsh:
9471 case Intrinsic::s390_vpklsf:
9472 case Intrinsic::s390_vpklsg:
9473 case Intrinsic::s390_vpklshs:
9474 case Intrinsic::s390_vpklsfs:
9475 case Intrinsic::s390_vpklsgs:
9477 SrcDemE = DemandedElts;
9480 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9483 case Intrinsic::s390_vuphb:
9484 case Intrinsic::s390_vuphh:
9485 case Intrinsic::s390_vuphf:
9486 case Intrinsic::s390_vuplhb:
9487 case Intrinsic::s390_vuplhh:
9488 case Intrinsic::s390_vuplhf:
9489 SrcDemE =
APInt(NumElts * 2, 0);
9492 case Intrinsic::s390_vuplb:
9493 case Intrinsic::s390_vuplhw:
9494 case Intrinsic::s390_vuplf:
9495 case Intrinsic::s390_vupllb:
9496 case Intrinsic::s390_vupllh:
9497 case Intrinsic::s390_vupllf:
9498 SrcDemE =
APInt(NumElts * 2, 0);
9501 case Intrinsic::s390_vpdi: {
9503 SrcDemE =
APInt(NumElts, 0);
9504 if (!DemandedElts[OpNo - 1])
9506 unsigned Mask =
Op.getConstantOperandVal(3);
9507 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9509 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9512 case Intrinsic::s390_vsldb: {
9514 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9515 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9516 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9517 unsigned NumSrc0Els = 16 - FirstIdx;
9518 SrcDemE =
APInt(NumElts, 0);
9520 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9523 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9528 case Intrinsic::s390_vperm:
9537 case SystemZISD::JOIN_DWORDS:
9539 SrcDemE =
APInt(1, 1);
9541 case SystemZISD::SELECT_CCMASK:
9542 SrcDemE = DemandedElts;
9553 const APInt &DemandedElts,
9568 const APInt &DemandedElts,
9570 unsigned Depth)
const {
9574 unsigned Tmp0, Tmp1;
9576 Known.Zero.setBitsFrom(2);
9579 EVT VT =
Op.getValueType();
9580 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9583 "KnownBits does not match VT in bitwidth");
9586 "DemandedElts does not match VT number of elements");
9588 unsigned Opcode =
Op.getOpcode();
9590 bool IsLogical =
false;
9591 unsigned Id =
Op.getConstantOperandVal(0);
9593 case Intrinsic::s390_vpksh:
9594 case Intrinsic::s390_vpksf:
9595 case Intrinsic::s390_vpksg:
9596 case Intrinsic::s390_vpkshs:
9597 case Intrinsic::s390_vpksfs:
9598 case Intrinsic::s390_vpksgs:
9599 case Intrinsic::s390_vpklsh:
9600 case Intrinsic::s390_vpklsf:
9601 case Intrinsic::s390_vpklsg:
9602 case Intrinsic::s390_vpklshs:
9603 case Intrinsic::s390_vpklsfs:
9604 case Intrinsic::s390_vpklsgs:
9605 case Intrinsic::s390_vpdi:
9606 case Intrinsic::s390_vsldb:
9607 case Intrinsic::s390_vperm:
9610 case Intrinsic::s390_vuplhb:
9611 case Intrinsic::s390_vuplhh:
9612 case Intrinsic::s390_vuplhf:
9613 case Intrinsic::s390_vupllb:
9614 case Intrinsic::s390_vupllh:
9615 case Intrinsic::s390_vupllf:
9618 case Intrinsic::s390_vuphb:
9619 case Intrinsic::s390_vuphh:
9620 case Intrinsic::s390_vuphf:
9621 case Intrinsic::s390_vuplb:
9622 case Intrinsic::s390_vuplhw:
9623 case Intrinsic::s390_vuplf: {
9638 case SystemZISD::JOIN_DWORDS:
9639 case SystemZISD::SELECT_CCMASK:
9642 case SystemZISD::REPLICATE: {
9665 if (
LHS == 1)
return 1;
9668 if (
RHS == 1)
return 1;
9669 unsigned Common = std::min(
LHS,
RHS);
9670 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9671 EVT VT =
Op.getValueType();
9673 if (SrcBitWidth > VTBits) {
9674 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9675 if (Common > SrcExtraBits)
9676 return (Common - SrcExtraBits);
9679 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9686 unsigned Depth)
const {
9687 if (
Op.getResNo() != 0)
9689 unsigned Opcode =
Op.getOpcode();
9691 unsigned Id =
Op.getConstantOperandVal(0);
9693 case Intrinsic::s390_vpksh:
9694 case Intrinsic::s390_vpksf:
9695 case Intrinsic::s390_vpksg:
9696 case Intrinsic::s390_vpkshs:
9697 case Intrinsic::s390_vpksfs:
9698 case Intrinsic::s390_vpksgs:
9699 case Intrinsic::s390_vpklsh:
9700 case Intrinsic::s390_vpklsf:
9701 case Intrinsic::s390_vpklsg:
9702 case Intrinsic::s390_vpklshs:
9703 case Intrinsic::s390_vpklsfs:
9704 case Intrinsic::s390_vpklsgs:
9705 case Intrinsic::s390_vpdi:
9706 case Intrinsic::s390_vsldb:
9707 case Intrinsic::s390_vperm:
9709 case Intrinsic::s390_vuphb:
9710 case Intrinsic::s390_vuphh:
9711 case Intrinsic::s390_vuphf:
9712 case Intrinsic::s390_vuplb:
9713 case Intrinsic::s390_vuplhw:
9714 case Intrinsic::s390_vuplf: {
9718 EVT VT =
Op.getValueType();
9728 case SystemZISD::SELECT_CCMASK:
9741 switch (
Op->getOpcode()) {
9742 case SystemZISD::PCREL_WRAPPER:
9743 case SystemZISD::PCREL_OFFSET:
9754 "Unexpected stack alignment");
9757 unsigned StackProbeSize =
9760 StackProbeSize &= ~(StackAlign - 1);
9761 return StackProbeSize ? StackProbeSize : StackAlign;
9800 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9802 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9808 if (miI ==
MBB->end()) {
9810 if (Succ->isLiveIn(SystemZ::CC))
9821 switch (
MI.getOpcode()) {
9822 case SystemZ::Select32:
9823 case SystemZ::Select64:
9824 case SystemZ::Select128:
9825 case SystemZ::SelectF32:
9826 case SystemZ::SelectF64:
9827 case SystemZ::SelectF128:
9828 case SystemZ::SelectVR32:
9829 case SystemZ::SelectVR64:
9830 case SystemZ::SelectVR128:
9862 for (
auto *
MI : Selects) {
9863 Register DestReg =
MI->getOperand(0).getReg();
9864 Register TrueReg =
MI->getOperand(1).getReg();
9865 Register FalseReg =
MI->getOperand(2).getReg();
9870 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9873 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9874 TrueReg = It->second.first;
9876 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9877 FalseReg = It->second.second;
9880 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9885 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9896 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9897 assert(TFL->hasReservedCallFrame(MF) &&
9898 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9903 uint32_t NumBytes =
MI.getOperand(0).getImm();
9908 MI.eraseFromParent();
9917 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9919 unsigned CCValid =
MI.getOperand(3).getImm();
9920 unsigned CCMask =
MI.getOperand(4).getImm();
9925 SmallVector<MachineInstr*, 8> Selects;
9926 SmallVector<MachineInstr*, 8> DbgValues;
9932 assert(NextMI.getOperand(3).getImm() == CCValid &&
9933 "Bad CCValid operands since CC was not redefined.");
9934 if (NextMI.getOperand(4).getImm() == CCMask ||
9935 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9941 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9942 NextMI.usesCustomInsertionHook())
9945 for (
auto *SelMI : Selects)
9946 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9950 if (NextMI.isDebugInstr()) {
9952 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9955 }
else if (User || ++
Count > 20)
9959 MachineInstr *LastMI = Selects.back();
9960 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9962 MachineBasicBlock *StartMBB =
MBB;
9992 for (
auto *SelMI : Selects)
9993 SelMI->eraseFromParent();
9996 for (
auto *DbgMI : DbgValues)
9997 MBB->
splice(InsertPos, StartMBB, DbgMI);
10008 unsigned StoreOpcode,
10009 unsigned STOCOpcode,
10010 bool Invert)
const {
10011 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10013 Register SrcReg =
MI.getOperand(0).getReg();
10014 MachineOperand
Base =
MI.getOperand(1);
10015 int64_t Disp =
MI.getOperand(2).getImm();
10016 Register IndexReg =
MI.getOperand(3).getReg();
10017 unsigned CCValid =
MI.getOperand(4).getImm();
10018 unsigned CCMask =
MI.getOperand(5).getImm();
10021 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10025 MachineMemOperand *MMO =
nullptr;
10026 for (
auto *
I :
MI.memoperands())
10027 if (
I->isStore()) {
10035 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10047 MI.eraseFromParent();
10055 MachineBasicBlock *StartMBB =
MBB;
10061 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10088 MI.eraseFromParent();
10098 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10106 MachineBasicBlock *StartMBB =
MBB;
10124 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10151 MI.eraseFromParent();
10162 bool Invert)
const {
10164 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10171 int64_t Disp =
MI.getOperand(2).getImm();
10173 Register BitShift =
MI.getOperand(4).getReg();
10174 Register NegBitShift =
MI.getOperand(5).getReg();
10175 unsigned BitSize =
MI.getOperand(6).getImm();
10179 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10180 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10181 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10191 MachineBasicBlock *StartMBB =
MBB;
10224 }
else if (BinOpcode)
10247 MI.eraseFromParent();
10258 unsigned KeepOldMask)
const {
10260 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10266 int64_t Disp =
MI.getOperand(2).getImm();
10268 Register BitShift =
MI.getOperand(4).getReg();
10269 Register NegBitShift =
MI.getOperand(5).getReg();
10270 unsigned BitSize =
MI.getOperand(6).getImm();
10274 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10275 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10276 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10287 MachineBasicBlock *StartMBB =
MBB;
10351 MI.eraseFromParent();
10361 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10367 int64_t Disp =
MI.getOperand(2).getImm();
10368 Register CmpVal =
MI.getOperand(3).getReg();
10369 Register OrigSwapVal =
MI.getOperand(4).getReg();
10370 Register BitShift =
MI.getOperand(5).getReg();
10371 Register NegBitShift =
MI.getOperand(6).getReg();
10372 int64_t BitSize =
MI.getOperand(7).getImm();
10378 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10379 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10380 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10381 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10393 MachineBasicBlock *StartMBB =
MBB;
10465 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10468 MI.eraseFromParent();
10476 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10481 .
add(
MI.getOperand(1))
10482 .
addImm(SystemZ::subreg_h64)
10483 .
add(
MI.getOperand(2))
10484 .
addImm(SystemZ::subreg_l64);
10485 MI.eraseFromParent();
10494 bool ClearEven)
const {
10496 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10518 MI.eraseFromParent();
10525 unsigned Opcode,
bool IsMemset)
const {
10527 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10532 uint64_t DestDisp =
MI.getOperand(1).getImm();
10537 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10540 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10550 SrcDisp =
MI.getOperand(3).getImm();
10552 SrcBase = DestBase;
10553 SrcDisp = DestDisp++;
10554 foldDisplIfNeeded(DestBase, DestDisp);
10557 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10558 bool IsImmForm = LengthMO.
isImm();
10559 bool IsRegForm = !IsImmForm;
10562 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10564 MachineOperand DBase, uint64_t DDisp,
10565 MachineOperand
SBase, uint64_t SDisp,
10566 unsigned Length) ->
void {
10570 if (ByteMO.
isImm())
10585 bool NeedsLoop =
false;
10586 uint64_t ImmLength = 0;
10587 Register LenAdjReg = SystemZ::NoRegister;
10589 ImmLength = LengthMO.
getImm();
10590 ImmLength += IsMemset ? 2 : 1;
10591 if (ImmLength == 0) {
10592 MI.eraseFromParent();
10595 if (Opcode == SystemZ::CLC) {
10596 if (ImmLength > 3 * 256)
10606 }
else if (ImmLength > 6 * 256)
10614 LenAdjReg = LengthMO.
getReg();
10619 MachineBasicBlock *EndMBB =
10620 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10628 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10638 auto loadZeroAddress = [&]() -> MachineOperand {
10643 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10644 DestBase = loadZeroAddress();
10645 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10646 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10648 MachineBasicBlock *StartMBB =
nullptr;
10649 MachineBasicBlock *LoopMBB =
nullptr;
10650 MachineBasicBlock *NextMBB =
nullptr;
10651 MachineBasicBlock *DoneMBB =
nullptr;
10652 MachineBasicBlock *AllDoneMBB =
nullptr;
10656 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10665 RC = &SystemZ::GR64BitRegClass;
10693 MBB = MemsetOneCheckMBB;
10704 MBB = MemsetOneMBB;
10736 if (EndMBB && !ImmLength)
10758 if (!HaveSingleBase)
10765 if (Opcode == SystemZ::MVC)
10792 if (!HaveSingleBase)
10815 Register RemDestReg = HaveSingleBase ? RemSrcReg
10820 if (!HaveSingleBase)
10828 MachineInstrBuilder EXRL_MIB =
10836 if (Opcode != SystemZ::MVC) {
10846 while (ImmLength > 0) {
10847 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10850 foldDisplIfNeeded(DestBase, DestDisp);
10851 foldDisplIfNeeded(SrcBase, SrcDisp);
10852 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10853 DestDisp += ThisLength;
10854 SrcDisp += ThisLength;
10855 ImmLength -= ThisLength;
10858 if (EndMBB && ImmLength > 0) {
10874 MI.eraseFromParent();
10883 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10887 uint64_t End1Reg =
MI.getOperand(0).getReg();
10888 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10889 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10890 uint64_t CharReg =
MI.getOperand(3).getReg();
10897 MachineBasicBlock *StartMBB =
MBB;
10933 MI.eraseFromParent();
10940 bool NoFloat)
const {
10942 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10943 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10946 MI.setDesc(
TII->get(Opcode));
10950 uint64_t Control =
MI.getOperand(2).getImm();
10951 static const unsigned GPRControlBit[16] = {
10952 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10953 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10955 Control |= GPRControlBit[15];
10956 if (TFI->
hasFP(MF))
10957 Control |= GPRControlBit[11];
10958 MI.getOperand(2).setImm(Control);
10961 for (
int I = 0;
I < 16;
I++) {
10962 if ((Control & GPRControlBit[
I]) == 0) {
10969 if (!NoFloat && (Control & 4) != 0) {
10970 if (Subtarget.hasVector()) {
10987 MachineRegisterInfo *MRI = &MF.
getRegInfo();
10988 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10991 Register SrcReg =
MI.getOperand(0).getReg();
11002 MI.eraseFromParent();
11010 MachineRegisterInfo *MRI = &MF.
getRegInfo();
11011 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11014 Register DstReg =
MI.getOperand(0).getReg();
11015 Register SizeReg =
MI.getOperand(2).getReg();
11017 MachineBasicBlock *StartMBB =
MBB;
11093 MI.eraseFromParent();
11097SDValue SystemZTargetLowering::
11100 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11112 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11117 .
addImm(
MI.getOperand(1).getImm());
11118 MI.eraseFromParent();
11124 switch (
MI.getOpcode()) {
11125 case SystemZ::ADJCALLSTACKDOWN:
11126 case SystemZ::ADJCALLSTACKUP:
11127 return emitAdjCallStack(
MI,
MBB);
11129 case SystemZ::Select32:
11130 case SystemZ::Select64:
11131 case SystemZ::Select128:
11132 case SystemZ::SelectF32:
11133 case SystemZ::SelectF64:
11134 case SystemZ::SelectF128:
11135 case SystemZ::SelectVR32:
11136 case SystemZ::SelectVR64:
11137 case SystemZ::SelectVR128:
11138 return emitSelect(
MI,
MBB);
11140 case SystemZ::CondStore8Mux:
11141 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11142 case SystemZ::CondStore8MuxInv:
11143 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11144 case SystemZ::CondStore16Mux:
11145 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11146 case SystemZ::CondStore16MuxInv:
11147 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11148 case SystemZ::CondStore32Mux:
11149 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11150 case SystemZ::CondStore32MuxInv:
11151 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11152 case SystemZ::CondStore8:
11153 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11154 case SystemZ::CondStore8Inv:
11155 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11156 case SystemZ::CondStore16:
11157 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11158 case SystemZ::CondStore16Inv:
11159 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11160 case SystemZ::CondStore32:
11161 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11162 case SystemZ::CondStore32Inv:
11163 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11164 case SystemZ::CondStore64:
11165 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11166 case SystemZ::CondStore64Inv:
11167 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11168 case SystemZ::CondStoreF32:
11169 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11170 case SystemZ::CondStoreF32Inv:
11171 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11172 case SystemZ::CondStoreF64:
11173 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11174 case SystemZ::CondStoreF64Inv:
11175 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11177 case SystemZ::SCmp128Hi:
11178 return emitICmp128Hi(
MI,
MBB,
false);
11179 case SystemZ::UCmp128Hi:
11180 return emitICmp128Hi(
MI,
MBB,
true);
11182 case SystemZ::PAIR128:
11183 return emitPair128(
MI,
MBB);
11184 case SystemZ::AEXT128:
11185 return emitExt128(
MI,
MBB,
false);
11186 case SystemZ::ZEXT128:
11187 return emitExt128(
MI,
MBB,
true);
11189 case SystemZ::ATOMIC_SWAPW:
11190 return emitAtomicLoadBinary(
MI,
MBB, 0);
11192 case SystemZ::ATOMIC_LOADW_AR:
11193 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11194 case SystemZ::ATOMIC_LOADW_AFI:
11195 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11197 case SystemZ::ATOMIC_LOADW_SR:
11198 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11200 case SystemZ::ATOMIC_LOADW_NR:
11201 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11202 case SystemZ::ATOMIC_LOADW_NILH:
11203 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11205 case SystemZ::ATOMIC_LOADW_OR:
11206 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11207 case SystemZ::ATOMIC_LOADW_OILH:
11208 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11210 case SystemZ::ATOMIC_LOADW_XR:
11211 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11212 case SystemZ::ATOMIC_LOADW_XILF:
11213 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11215 case SystemZ::ATOMIC_LOADW_NRi:
11216 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11217 case SystemZ::ATOMIC_LOADW_NILHi:
11218 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11220 case SystemZ::ATOMIC_LOADW_MIN:
11222 case SystemZ::ATOMIC_LOADW_MAX:
11224 case SystemZ::ATOMIC_LOADW_UMIN:
11226 case SystemZ::ATOMIC_LOADW_UMAX:
11229 case SystemZ::ATOMIC_CMP_SWAPW:
11230 return emitAtomicCmpSwapW(
MI,
MBB);
11231 case SystemZ::MVCImm:
11232 case SystemZ::MVCReg:
11233 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11234 case SystemZ::NCImm:
11235 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11236 case SystemZ::OCImm:
11237 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11238 case SystemZ::XCImm:
11239 case SystemZ::XCReg:
11240 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11241 case SystemZ::CLCImm:
11242 case SystemZ::CLCReg:
11243 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11244 case SystemZ::MemsetImmImm:
11245 case SystemZ::MemsetImmReg:
11246 case SystemZ::MemsetRegImm:
11247 case SystemZ::MemsetRegReg:
11248 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11249 case SystemZ::CLSTLoop:
11250 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11251 case SystemZ::MVSTLoop:
11252 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11253 case SystemZ::SRSTLoop:
11254 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11255 case SystemZ::TBEGIN:
11256 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11257 case SystemZ::TBEGIN_nofloat:
11258 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11259 case SystemZ::TBEGINC:
11260 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11261 case SystemZ::LTEBRCompare_Pseudo:
11262 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11263 case SystemZ::LTDBRCompare_Pseudo:
11264 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11265 case SystemZ::LTXBRCompare_Pseudo:
11266 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11268 case SystemZ::PROBED_ALLOCA:
11269 return emitProbedAlloca(
MI,
MBB);
11270 case SystemZ::EH_SjLj_SetJmp:
11272 case SystemZ::EH_SjLj_LongJmp:
11275 case TargetOpcode::STACKMAP:
11276 case TargetOpcode::PATCHPOINT:
11279 case SystemZ::MOV_STACKGUARD_DAG:
11280 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11282 case SystemZ::CMP_STACKGUARD_DAG:
11283 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11293SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11294 if (VT == MVT::Untyped)
11295 return &SystemZ::ADDR128BitRegClass;
11321 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11341 EVT VT =
Op.getValueType();
11342 Op =
Op.getOperand(0);
11343 EVT OpVT =
Op.getValueType();
11345 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11356 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11376 const AttributeList &Attrs =
F->getAttributes();
11377 if (Attrs.hasRetAttrs())
11378 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11379 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11380 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11383 OS << *FT->getParamType(
I);
11385 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11392bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11393 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11394 if (Itr == IsInternalCache.end())
11395 Itr = IsInternalCache
11396 .insert(std::pair<const Function *, bool>(
11399 return Itr->second;
11402void SystemZTargetLowering::
11410 bool IsInternal =
false;
11411 const Function *CalleeFn =
nullptr;
11414 IsInternal = isInternal(CalleeFn);
11415 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11416 errs() <<
"ERROR: Missing extension attribute of passed "
11417 <<
"value in call to function:\n" <<
"Callee: ";
11418 if (CalleeFn !=
nullptr)
11422 errs() <<
"Caller: ";
11428void SystemZTargetLowering::
11436 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11437 errs() <<
"ERROR: Missing extension attribute of returned "
11438 <<
"value from function:\n";
11446bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11448 if (!Subtarget.isTargetELF())
11457 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11458 MVT VT = Outs[i].VT;
11459 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11462 "Unexpected integer argument VT.");
11463 if (VT == MVT::i32 &&
11474 StringRef GuardMode = M.getStackProtectorGuard();
11477 if (GuardMode ==
"tls" || GuardMode.
empty())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
static bool isZeroVector(SDValue N)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
Function Alias Analysis Results
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isSelectPseudo(MachineInstr &MI)
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallSet class.
static SDValue getI128Select(SelectionDAG &DAG, const SDLoc &DL, Comparison C, SDValue TrueOp, SDValue FalseOp)
static SmallVector< SDValue, 4 > simplifyAssumingCCVal(SDValue &Val, SDValue &CC, SelectionDAG &DAG)
static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS)
static void adjustForLTGFR(Comparison &C)
static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0, SDValue Op1)
static cl::opt< bool > EnableIntArgExtCheck("argext-abi-check", cl::init(false), cl::desc("Verify that narrow int args are properly extended per the " "SystemZ ABI."))
static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG)
static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT, unsigned Opcode, SDValue Op0, SDValue Op1, SDValue &Even, SDValue &Odd)
static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)
static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Value)
static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In)
static bool isSimpleShift(SDValue N, unsigned &ShiftVal)
static SDValue mergeHighParts(SelectionDAG &DAG, const SDLoc &DL, unsigned MergedBits, EVT VT, SDValue Op0, SDValue Op1)
static bool isI128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static bool chooseShuffleOpNos(int *OpNos, unsigned &OpNo0, unsigned &OpNo1)
static uint32_t findZeroVectorIdx(SDValue *Ops, unsigned Num)
static bool isVectorElementSwap(ArrayRef< int > M, EVT VT)
static void getCSAddressAndShifts(SDValue Addr, SelectionDAG &DAG, SDLoc DL, SDValue &AlignedAddr, SDValue &BitShift, SDValue &NegBitShift)
static bool isShlDoublePermute(const SmallVectorImpl< int > &Bytes, unsigned &StartIndex, unsigned &OpNo0, unsigned &OpNo1)
static SDValue getPermuteNode(SelectionDAG &DAG, const SDLoc &DL, const Permute &P, SDValue Op0, SDValue Op1)
static SDNode * emitIntrinsicWithCCAndChain(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static SDValue getCCResult(SelectionDAG &DAG, SDValue CCReg)
static void adjustForStackGuardCompare(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend, SDValue Op0, SDValue Op1, SDValue &Hi, SDValue &Lo)
static bool isF128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static void createPHIsForSelects(SmallVector< MachineInstr *, 8 > &Selects, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, MachineBasicBlock *SinkMBB)
static SDValue getGeneralPermuteNode(SelectionDAG &DAG, const SDLoc &DL, SDValue *Ops, const SmallVectorImpl< int > &Bytes)
static unsigned getVectorComparisonOrInvert(ISD::CondCode CC, CmpMode Mode, bool &Invert)
static unsigned CCMaskForCondCode(ISD::CondCode CC)
static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void adjustForFNeg(Comparison &C)
static bool isScalarToVector(SDValue Op)
static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue CCReg, unsigned CCValid, unsigned CCMask)
static bool matchPermute(const SmallVectorImpl< int > &Bytes, const Permute &P, unsigned &OpNo0, unsigned &OpNo1)
static bool isAddCarryChain(SDValue Carry)
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static MachineOperand earlyUseOperand(MachineOperand Op)
static bool canUseSiblingCall(const CCState &ArgCCInfo, SmallVectorImpl< CCValAssign > &ArgLocs, SmallVectorImpl< ISD::OutputArg > &Outs)
static bool getzOSCalleeAndADA(SelectionDAG &DAG, SDValue &Callee, SDValue &ADA, SDLoc &DL, SDValue &Chain)
static SDValue convertToF16(SDValue Op, SelectionDAG &DAG)
static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask, SelectionDAG &DAG)
static bool shouldSwapCmpOperands(const Comparison &C)
static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType)
static SDValue getADAEntry(SelectionDAG &DAG, SDValue Val, SDLoc DL, unsigned Offset, bool LoadAdr=false)
static SDNode * emitIntrinsicWithCC(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static void adjustForSubtraction(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool getVPermMask(SDValue ShuffleOp, SmallVectorImpl< int > &Bytes)
static const Permute PermuteForms[]
static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static std::pair< SDValue, int > findCCUse(const SDValue &Val, unsigned Depth=0)
static bool isSubBorrowChain(SDValue Carry)
static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool analyzeArgSplit(const SmallVectorImpl< ArgTy > &Args, SmallVector< CCValAssign, 16 > &ArgLocs, unsigned I, MVT &PartVT, unsigned &NumParts)
static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts, unsigned OpNo)
static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op, bool IsNegative)
static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static SDValue expandBitCastI128ToF128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static SDValue tryBuildVectorShuffle(SelectionDAG &DAG, BuildVectorSDNode *BVN)
static SDValue convertFromF16(SDValue Op, SDLoc DL, SelectionDAG &DAG)
static unsigned getVectorComparison(ISD::CondCode CC, CmpMode Mode)
static SDValue lowerGR128ToI128(SelectionDAG &DAG, SDValue In)
static SDValue MergeInputChains(SDNode *N1, SDNode *N2)
static SDValue expandBitCastF128ToI128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, uint64_t Mask, uint64_t CmpVal, unsigned ICmpType)
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL, SDValue Op, SDValue Chain)
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static bool checkCCKill(MachineInstr &MI, MachineBasicBlock *MBB)
static Register forceReg(MachineInstr &MI, MachineOperand &Base, const SystemZInstrInfo *TII)
static bool is32Bit(EVT VT)
static std::pair< unsigned, const TargetRegisterClass * > parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC, const unsigned *Map, unsigned Size)
static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, const SystemZSubtarget &Subtarget, SDValue &Op)
static bool matchDoublePermute(const SmallVectorImpl< int > &Bytes, const Permute &P, SmallVectorImpl< int > &Transform)
static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, SDValue Call, unsigned CCValid, uint64_t CC, ISD::CondCode Cond)
static SDValue buildFPVecFromScalars4(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SmallVectorImpl< SDValue > &Elems, unsigned Pos)
static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg)
static AddressingMode getLoadStoreAddrMode(bool HasVector, Type *Ty)
static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Op0, SDValue Op1)
static void computeKnownBitsBinOp(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static bool getShuffleInput(const SmallVectorImpl< int > &Bytes, unsigned Start, unsigned BytesPerElement, int &Base)
static AddressingMode supportedAddressingMode(Instruction *I, bool HasVector)
static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isSingleWord() const
Determine if this APInt just has one word to store value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
LLVM Basic Block Representation.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI bool isConstant() const
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
const Constant * getConstVal() const
uint64_t getZExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false, bool IgnoreCastedDirectCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Tracks which library functions to use for a particular subtarget.
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()
uint64_t getScalarSizeInBits() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setAdjustsStack(bool V)
void setFrameAddressIsTaken(bool T)
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
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,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
MachineMemOperand * getMemOperand() const
Return the unique 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.
A Module instance is used to store all the information related to an LLVM module.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
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.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue 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
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A SystemZ-specific class detailing special use registers particular for calling conventions.
virtual int getStackPointerBias()=0
virtual int getReturnFunctionAddressRegister()=0
virtual int getCallFrameSize()=0
virtual int getStackPointerRegister()=0
static SystemZConstantPoolValue * Create(const GlobalValue *GV, SystemZCP::SystemZCPModifier Modifier)
unsigned getVarArgsFrameIndex() const
void setVarArgsFrameIndex(unsigned FI)
void setRegSaveFrameIndex(unsigned FI)
void incNumLocalDynamicTLSAccesses()
Register getVarArgsFirstGPR() const
void setADAVirtualRegister(Register Reg)
void setVarArgsFirstGPR(Register GPR)
Register getADAVirtualRegister() const
void setSizeOfFnParams(unsigned Size)
void setVarArgsFirstFPR(Register FPR)
unsigned getRegSaveFrameIndex() const
Register getVarArgsFirstFPR() const
const SystemZInstrInfo * getInstrInfo() const override
SystemZCallingConventionRegisters * getSpecialRegisters() const
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be cast by the IR-level AtomicExpand pass.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &, EVT) const override
Return the ValueType of the result of SETCC operations.
bool allowTruncateForTailCall(Type *, Type *) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag, const SDLoc &DL, const AsmOperandInfo &Constraint, SelectionDAG &DAG) const override
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool useSoftFloat() const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
std::pair< SDValue, SDValue > makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT, ArrayRef< SDValue > Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL, bool DoesNotReturn, bool IsReturnValueUsed) const
void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const override
Insert SSP declaration if global stack protector is used.
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, unsigned Depth) const override
Return true if this function can prove that Op is never poison and, Kind can be used to track poison ...
SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI)
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
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...
CondMergingParams getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs, const Function *F) const override
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be cast by the IR-level AtomicExpand pass into.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
unsigned getStackProbeSize(const MachineFunction &MF) const
XPLINK64 calling convention specific use registers Particular to z/OS when in 64 bit mode.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
virtual void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Let target indicate that an extending atomic load of the specified type is legal.
virtual unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const
Determines the optimal series of memory ops to replace the memset / memcpy.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
unsigned getPointerSize(unsigned AS) const
Get the pointer size for this target.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ PSEUDO_FMIN
PSEUDO_FMIN is strictly equivalent to op0 olt op1 ?
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - minimumnum/maximumnum that is same with FMINNUM_IEEE and FMAXNUM_IEEE besid...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are 0 o...
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
auto m_Cmp()
Matches any compare instruction and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ System
Synchronized with respect to all concurrently executing threads.
@ MO_ADA_DATA_SYMBOL_ADDR
@ MO_ADA_DIRECT_FUNC_DESC
@ MO_ADA_INDIRECT_FUNC_DESC
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const int64_t ELFCallFrameSize
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned VR32Regs[32]
unsigned odd128(bool Is32bit)
const unsigned CCMASK_CMP_GE
static bool isImmHH(uint64_t Val)
const unsigned CCMASK_TEND
const unsigned CCMASK_CS_EQ
const unsigned CCMASK_TBEGIN
const MCPhysReg ELFArgFPRs[ELFNumArgFPRs]
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_TM_SOME_1
const unsigned CCMASK_LOGICAL_CARRY
const unsigned TDCMASK_NORMAL_MINUS
const unsigned CCMASK_TDC
const unsigned CCMASK_FCMP
const unsigned CCMASK_TM_SOME_0
static bool isImmHL(uint64_t Val)
const unsigned TDCMASK_SUBNORMAL_MINUS
const unsigned TDCMASK_NORMAL_PLUS
const unsigned CCMASK_CMP_GT
const unsigned TDCMASK_QNAN_MINUS
const unsigned CCMASK_ANY
const unsigned CCMASK_ARITH
const unsigned CCMASK_TM_MIXED_MSB_0
const unsigned TDCMASK_SUBNORMAL_PLUS
static bool isImmLL(uint64_t Val)
const unsigned VectorBits
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned TDCMASK_INFINITY_PLUS
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_TM_ALL_0
const unsigned CCMASK_CMP_LE
const unsigned CCMASK_CMP_O
const unsigned CCMASK_CMP_EQ
const unsigned VectorBytes
const unsigned TDCMASK_INFINITY_MINUS
const unsigned CCMASK_ICMP
const unsigned CCMASK_VCMP_ALL
const unsigned CCMASK_VCMP_NONE
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_VCMP
const unsigned CCMASK_TM_MIXED_MSB_1
const unsigned CCMASK_TM_MSB_0
const unsigned CCMASK_ARITH_OVERFLOW
const unsigned CCMASK_CS_NE
const unsigned TDCMASK_SNAN_PLUS
const unsigned CCMASK_NONE
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
const unsigned TDCMASK_ZERO_PLUS
const unsigned TDCMASK_QNAN_PLUS
const unsigned TDCMASK_ZERO_MINUS
unsigned even128(bool Is32bit)
const unsigned CCMASK_TM_ALL_1
const unsigned CCMASK_LOGICAL_BORROW
const unsigned ELFNumArgFPRs
const unsigned CCMASK_CMP_UO
const unsigned CCMASK_LOGICAL
const unsigned CCMASK_TM_MSB_1
const unsigned TDCMASK_SNAN_MINUS
initializer< Ty > init(const Ty &Val)
support::ulittle32_t Word
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
@ Define
Register definition.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
testing::Matcher< const detail::ErrorHolder & > Failed()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
LLVM_ABI void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
AddressingMode(bool LongDispl, bool IdxReg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isVectorOf(EVT EltVT) const
Return true if this is a vector with matching element type.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
SystemZVectorConstantInfo(APInt IntImm)
SmallVector< unsigned, 2 > OpVals
bool isVectorConstantLegal(const SystemZSubtarget &Subtarget)
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDiscardResult(bool Value=true)
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
CallLoweringInfo & setNoReturn(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
This structure is used to pass arguments to makeLibCall function.