25#include "llvm/IR/IntrinsicsS390.h"
37#define DEBUG_TYPE "systemz-lower"
43 cl::desc(
"Verify that narrow int args are properly extended per the "
50 : Op0(Op0In), Op1(Op1In), Chain(ChainIn),
51 Opcode(0), ICmpType(0), CCValid(0), CCMask(0) {}
101 if (Subtarget.hasHighWord())
107 if (Subtarget.hasVector()) {
116 if (Subtarget.hasVectorEnhancements1())
121 if (Subtarget.hasVector()) {
131 if (Subtarget.hasVector())
136 if (!Subtarget.hasVector())
162 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
163 I <= MVT::LAST_FP_VALUETYPE;
189 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
190 I <= MVT::LAST_INTEGER_VALUETYPE;
221 if (Subtarget.hasPopulationCount())
247 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
268 if (!Subtarget.hasVectorEnhancements3()) {
295 if (Subtarget.hasVectorEnhancements3()) {
320 {MVT::i8, MVT::i16},
Custom);
332 {MVT::i8, MVT::i16, MVT::i32},
Legal);
334 {MVT::i8, MVT::i16},
Legal);
355 if (Subtarget.hasMiscellaneousExtensions4()) {
362 if (Subtarget.hasMiscellaneousExtensions3()) {
447 if (!Subtarget.hasVector()) {
465 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
470 if (Subtarget.hasVectorEnhancements3() &&
471 VT != MVT::v16i8 && VT != MVT::v8i16) {
481 if (Subtarget.hasVectorEnhancements1())
515 if (Subtarget.hasVector()) {
537 if (Subtarget.hasVectorEnhancements2()) {
563 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
577 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
578 I <= MVT::LAST_FP_VALUETYPE;
586 if (Subtarget.hasFPExtension()) {
614 if (Subtarget.hasFPExtension()) {
630 if (Subtarget.hasVector()) {
681 if (Subtarget.hasVectorEnhancements1()) {
688 if (Subtarget.hasVectorEnhancements1()) {
705 for (
MVT Type : {MVT::f64, MVT::v2f64, MVT::f32, MVT::v4f32, MVT::f128}) {
730 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
731 MVT::v4f32, MVT::v2f64 }) {
742 if (!Subtarget.hasVectorEnhancements1()) {
748 if (Subtarget.hasVectorEnhancements1())
758 if (Subtarget.hasVectorEnhancements1()) {
770 if (!Subtarget.hasVector()) {
781 if (Subtarget.isTargetzOS()) {
846 return Subtarget.hasSoftFloat();
867 if (!Subtarget.hasVector() || VT.
getScalarType() == MVT::f16)
877 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
879 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16)) {
880 IntermediateVT = RegisterVT = MVT::v8f16;
881 return NumIntermediates =
885 Context,
CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
888 if (RegisterVT == MVT::v2i64 && !Subtarget.hasVector()) {
889 IntermediateVT = RegisterVT = MVT::i64;
890 NumIntermediates *= 2;
905 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
909 if (RegisterVT == MVT::v2i64 && !Subtarget.hasVector())
917 if (Subtarget.hasVector() && VT.
isVectorOf(MVT::f16))
923 if (RegisterVT == MVT::v2i64 && !Subtarget.hasVector())
950 return Subtarget.hasVectorEnhancements1();
964 (isFP128 && !
Subtarget.hasVectorEnhancements1()))
973 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
980 Opcode = SystemZISD::BYTE_MASK;
986 if (SplatBitSize > 64)
989 auto TryValue = [&](uint64_t
Value) ->
bool {
993 OpVals.push_back(((
unsigned) SignedValue));
994 Opcode = SystemZISD::REPLICATE;
1000 unsigned Start,
End;
1001 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start,
End)) {
1005 OpVals.push_back(Start - (64 - SplatBitSize));
1006 OpVals.push_back(
End - (64 - SplatBitSize));
1007 Opcode = SystemZISD::ROTATE_MASK;
1019 uint64_t SplatBitsZ = SplatBits.getZExtValue();
1020 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
1032 return TryValue(SplatBitsZ | Middle);
1041 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
1047 unsigned HalfSize = Width / 2;
1052 if (HighValue != LowValue || 8 > HalfSize)
1055 SplatBits = HighValue;
1059 SplatBitSize = Width;
1067 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1071 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1077 bool ForCodeSize)
const {
1079 if (
Imm.isZero() ||
Imm.isNegZero())
1102 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1104 Register MainDstReg =
MRI.createVirtualRegister(RC);
1105 Register RestoreDstReg =
MRI.createVirtualRegister(RC);
1108 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1161 const int64_t FPOffset = 0;
1170 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
1182 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1183 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1186 .
addReg(SpecialRegs->getFramePointerRegister())
1194 .
addReg(SpecialRegs->getStackPointerRegister())
1202 Register BCReg =
MRI.createVirtualRegister(PtrRC);
1205 .
addReg(SpecialRegs->getStackPointerRegister())
1206 .
addImm(TFL->getBackchainOffset(*MF))
1217 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1221 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1242 MI.eraseFromParent();
1258 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1261 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1268 const int64_t FPOffset = 0;
1280 SpecialRegs->getFramePointerRegister())
1302 SpecialRegs->getStackPointerRegister())
1311 .
addReg(SpecialRegs->getStackPointerRegister())
1312 .
addImm(TFL->getBackchainOffset(*MF))
1318 MI.eraseFromParent();
1325 return MemVT != MVT::v2i64 || Subtarget.hasVector();
1331 return !Subtarget.hasVector();
1361 if (Subtarget.hasInterlockedAccess1() &&
1394 EVT VT =
Y.getValueType();
1397 if (VT == MVT::i32 || VT == MVT::i64)
1398 return Subtarget.hasMiscellaneousExtensions3();
1401 if (VT.
isVector() || VT == MVT::i128)
1402 return Subtarget.hasVector();
1430 bool MVC = Ty->isIntegerTy(8);
1436static AddressingMode
1439 switch (
II->getIntrinsicID()) {
1441 case Intrinsic::memset:
1442 case Intrinsic::memmove:
1443 case Intrinsic::memcpy:
1450 if (SingleUser->getParent() ==
I->getParent()) {
1453 if (
C->getBitWidth() <= 64 &&
1463 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1477 I->getOperand(0)->getType());
1479 bool IsVectorAccess = MemAccessTy->isVectorTy();
1484 Value *DataOp =
I->getOperand(0);
1486 IsVectorAccess =
true;
1492 User *LoadUser = *
I->user_begin();
1494 IsVectorAccess =
true;
1497 if (IsFPAccess || IsVectorAccess)
1516 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1526 return AM.
Scale == 0;
1533 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1534 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1538 "Expected EmitTargetCodeForMemXXX() to handle AlwaysInline cases.");
1540 if (
Op.isZeroMemset())
1543 const int MVCFastLen = 16;
1546 if (
Op.isMemcpy() &&
Op.size() <= MVCFastLen)
1548 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1552 if ((
Op.size() >= 16 && !
Op.isAligned(
Align(8))) ||
1553 (
Op.size() >= 25 &&
Op.size() <= 31))
1557 Context, MemOps, Limit,
Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1563 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1567 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1569 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1571 return FromBits > ToBits;
1579 return FromBits > ToBits;
1583 unsigned Opc =
N->getOpcode();
1596 if (Constraint.
size() == 1) {
1597 switch (Constraint[0]) {
1623 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1624 switch (Constraint[1]) {
1635 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1645 Value *CallOperandVal = Info.CallOperandVal;
1648 if (!CallOperandVal)
1652 switch (*Constraint) {
1671 if (Subtarget.hasVector())
1702 if (
C->getZExtValue() == 0x7fffffff)
1712static std::pair<unsigned, const TargetRegisterClass *>
1714 const unsigned *Map,
unsigned Size) {
1715 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1716 if (isdigit(Constraint[2])) {
1721 return std::make_pair(Map[Index], RC);
1723 return std::make_pair(0U,
nullptr);
1726std::pair<unsigned, const TargetRegisterClass *>
1729 if (Constraint.
size() == 1) {
1731 switch (Constraint[0]) {
1736 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1738 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1739 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1743 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1744 else if (VT == MVT::i128)
1745 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1746 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1749 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1754 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1756 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1758 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1759 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1764 if (Subtarget.hasVector()) {
1766 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1768 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1770 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1771 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1780 auto getVTSizeInBits = [&VT]() {
1788 if (Constraint[1] ==
'r') {
1789 if (getVTSizeInBits() == 32)
1792 if (getVTSizeInBits() == 128)
1798 if (Constraint[1] ==
'f') {
1800 return std::make_pair(
1802 if (getVTSizeInBits() == 16)
1805 if (getVTSizeInBits() == 32)
1808 if (getVTSizeInBits() == 128)
1814 if (Constraint[1] ==
'v') {
1815 if (!Subtarget.hasVector())
1816 return std::make_pair(
1818 if (getVTSizeInBits() == 16)
1821 if (getVTSizeInBits() == 32)
1824 if (getVTSizeInBits() == 64)
1830 if (Constraint[1] ==
'@') {
1831 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1832 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1845 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1846 : SystemZ::NoRegister)
1848 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1856 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1861 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1876 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1880 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1881 OpInfo.ConstraintVT.getSizeInBits() < 8)
1896 if (Constraint.
size() == 1) {
1897 switch (Constraint[0]) {
1902 Op.getValueType()));
1909 Op.getValueType()));
1916 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1923 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1928 if (
C->getZExtValue() == 0x7fffffff)
1930 Op.getValueType()));
1941#define GET_CALLING_CONV_IMPL
1942#include "SystemZGenCallingConv.inc"
1946 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1952 Type *ToType)
const {
2015 if (BitCastToType == MVT::v2i64)
2039 return DAG.
getNode(SystemZISD::PAIR128,
DL, MVT::v2i64,
Hi,
Lo);
2062 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
2075 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID>
CC)
const {
2087template <
class ArgTy>
2091 if (!Args[
I].Flags.isSplit())
2095 PartVT = ArgLocs[
I].getValVT();
2097 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2098 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2099 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2101 if (Args[PartIdx].Flags.isSplitEnd())
2119 ADAvReg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
2122 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2145 unsigned NumFixedGPRs = 0;
2146 unsigned NumFixedFPRs = 0;
2147 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2160 RC = &SystemZ::GR32BitRegClass;
2164 RC = &SystemZ::GR64BitRegClass;
2168 RC = &SystemZ::FP16BitRegClass;
2172 RC = &SystemZ::FP32BitRegClass;
2176 RC = &SystemZ::FP64BitRegClass;
2180 RC = &SystemZ::FP128BitRegClass;
2189 RC = &SystemZ::VR128BitRegClass;
2203 if (Subtarget.isTargetXPLINK64()) {
2206 ArgSPOffset += XPRegs.getCallFrameSize();
2217 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2221 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2235 for (
unsigned PartIdx = 1; PartIdx <
NumParts; ++PartIdx) {
2238 unsigned PartOffset = Ins[
I].PartOffset;
2243 assert(PartOffset &&
"Offset should be non-zero.");
2246 }
else if (Subtarget.isTargetXPLINK64() &&
2249 Ins[
I].ArgVT.isSimple()) {
2254 MVT OrigVT = Ins[
I].ArgVT.getSimpleVT();
2260 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2266 Subtarget.getSpecialRegisters());
2272 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2277 if (IsVarArg && Subtarget.isTargetELF()) {
2290 int64_t RegSaveOffset =
2305 &SystemZ::FP64BitRegClass);
2326 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2333 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2335 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2342 unsigned Offset,
bool LoadAdr =
false) {
2364 bool LoadAddr =
false;
2386 unsigned ADADelta = 0;
2387 unsigned EPADelta = 8;
2393 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2394 G->getGlobal()->hasPrivateLinkage());
2399 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2445 if (Subtarget.isTargetXPLINK64()) {
2452 verifyNarrowIntegerArgs_Call(CLI, Outs, &MF.
getFunction(), Callee);
2456 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2466 "site marked musttail");
2479 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2491 SlotVT = Outs[
I].VT;
2498 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2501 assert(Outs[
I].PartOffset == 0);
2502 for (
unsigned PartIdx = 1; PartIdx <
NumParts; ++PartIdx) {
2505 unsigned PartOffset = Outs[
I].PartOffset;
2511 assert(PartOffset &&
"Offset should be non-zero.");
2513 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2515 ArgValue = SpillSlot;
2532 if (!StackPtr.getNode())
2539 else if (VA.
getLocVT() == MVT::f16)
2552 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2556 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2562 if (!MemOpChains.
empty())
2570 if (Subtarget.isTargetXPLINK64()) {
2575 ->getAddressOfCalleeRegister();
2578 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2585 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2588 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2589 }
else if (IsTailCall) {
2592 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2597 for (
const auto &[Reg,
N] : RegsToPass) {
2604 Ops.push_back(Chain);
2605 Ops.push_back(Callee);
2609 for (
const auto &[Reg,
N] : RegsToPass)
2614 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2615 assert(Mask &&
"Missing call preserved mask for calling convention");
2620 Ops.push_back(Glue);
2629 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2639 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2646 VA.getLocVT(), Glue);
2663 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2665 Args.reserve(
Ops.size());
2671 Entry.IsZExt = !Entry.IsSExt;
2672 Args.push_back(Entry);
2683 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2694 const Type *RetTy)
const {
2697 for (
auto &Out : Outs)
2698 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2702 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2703 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2715 verifyNarrowIntegerArgs_Ret(CallConv, Outs, &MF.
getFunction());
2723 if (RetLocs.
empty())
2724 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2733 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2755 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2762 unsigned &CCValid) {
2763 unsigned Id =
Op.getConstantOperandVal(1);
2765 case Intrinsic::s390_tbegin:
2766 Opcode = SystemZISD::TBEGIN;
2770 case Intrinsic::s390_tbegin_nofloat:
2771 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2775 case Intrinsic::s390_tend:
2776 Opcode = SystemZISD::TEND;
2789 unsigned Id =
Op.getConstantOperandVal(0);
2791 case Intrinsic::s390_vpkshs:
2792 case Intrinsic::s390_vpksfs:
2793 case Intrinsic::s390_vpksgs:
2794 Opcode = SystemZISD::PACKS_CC;
2798 case Intrinsic::s390_vpklshs:
2799 case Intrinsic::s390_vpklsfs:
2800 case Intrinsic::s390_vpklsgs:
2801 Opcode = SystemZISD::PACKLS_CC;
2805 case Intrinsic::s390_vceqbs:
2806 case Intrinsic::s390_vceqhs:
2807 case Intrinsic::s390_vceqfs:
2808 case Intrinsic::s390_vceqgs:
2809 case Intrinsic::s390_vceqqs:
2810 Opcode = SystemZISD::VICMPES;
2814 case Intrinsic::s390_vchbs:
2815 case Intrinsic::s390_vchhs:
2816 case Intrinsic::s390_vchfs:
2817 case Intrinsic::s390_vchgs:
2818 case Intrinsic::s390_vchqs:
2819 Opcode = SystemZISD::VICMPHS;
2823 case Intrinsic::s390_vchlbs:
2824 case Intrinsic::s390_vchlhs:
2825 case Intrinsic::s390_vchlfs:
2826 case Intrinsic::s390_vchlgs:
2827 case Intrinsic::s390_vchlqs:
2828 Opcode = SystemZISD::VICMPHLS;
2832 case Intrinsic::s390_vtm:
2833 Opcode = SystemZISD::VTM;
2837 case Intrinsic::s390_vfaebs:
2838 case Intrinsic::s390_vfaehs:
2839 case Intrinsic::s390_vfaefs:
2840 Opcode = SystemZISD::VFAE_CC;
2844 case Intrinsic::s390_vfaezbs:
2845 case Intrinsic::s390_vfaezhs:
2846 case Intrinsic::s390_vfaezfs:
2847 Opcode = SystemZISD::VFAEZ_CC;
2851 case Intrinsic::s390_vfeebs:
2852 case Intrinsic::s390_vfeehs:
2853 case Intrinsic::s390_vfeefs:
2854 Opcode = SystemZISD::VFEE_CC;
2858 case Intrinsic::s390_vfeezbs:
2859 case Intrinsic::s390_vfeezhs:
2860 case Intrinsic::s390_vfeezfs:
2861 Opcode = SystemZISD::VFEEZ_CC;
2865 case Intrinsic::s390_vfenebs:
2866 case Intrinsic::s390_vfenehs:
2867 case Intrinsic::s390_vfenefs:
2868 Opcode = SystemZISD::VFENE_CC;
2872 case Intrinsic::s390_vfenezbs:
2873 case Intrinsic::s390_vfenezhs:
2874 case Intrinsic::s390_vfenezfs:
2875 Opcode = SystemZISD::VFENEZ_CC;
2879 case Intrinsic::s390_vistrbs:
2880 case Intrinsic::s390_vistrhs:
2881 case Intrinsic::s390_vistrfs:
2882 Opcode = SystemZISD::VISTR_CC;
2886 case Intrinsic::s390_vstrcbs:
2887 case Intrinsic::s390_vstrchs:
2888 case Intrinsic::s390_vstrcfs:
2889 Opcode = SystemZISD::VSTRC_CC;
2893 case Intrinsic::s390_vstrczbs:
2894 case Intrinsic::s390_vstrczhs:
2895 case Intrinsic::s390_vstrczfs:
2896 Opcode = SystemZISD::VSTRCZ_CC;
2900 case Intrinsic::s390_vstrsb:
2901 case Intrinsic::s390_vstrsh:
2902 case Intrinsic::s390_vstrsf:
2903 Opcode = SystemZISD::VSTRS_CC;
2907 case Intrinsic::s390_vstrszb:
2908 case Intrinsic::s390_vstrszh:
2909 case Intrinsic::s390_vstrszf:
2910 Opcode = SystemZISD::VSTRSZ_CC;
2914 case Intrinsic::s390_vfcedbs:
2915 case Intrinsic::s390_vfcesbs:
2916 Opcode = SystemZISD::VFCMPES;
2920 case Intrinsic::s390_vfchdbs:
2921 case Intrinsic::s390_vfchsbs:
2922 Opcode = SystemZISD::VFCMPHS;
2926 case Intrinsic::s390_vfchedbs:
2927 case Intrinsic::s390_vfchesbs:
2928 Opcode = SystemZISD::VFCMPHES;
2932 case Intrinsic::s390_vftcidb:
2933 case Intrinsic::s390_vftcisb:
2934 Opcode = SystemZISD::VFTCI;
2938 case Intrinsic::s390_tdc:
2939 Opcode = SystemZISD::TDC;
2952 unsigned NumOps =
Op.getNumOperands();
2955 Ops.push_back(
Op.getOperand(0));
2957 Ops.push_back(
Op.getOperand(
I));
2959 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2973 unsigned NumOps =
Op.getNumOperands();
2979 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2980 "Unhandled intrinsic with f16 operand.");
2983 Ops.push_back(CurrOper);
2997 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2998 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2999 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
3025 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
3028 int64_t
Value = ConstOp1->getSExtValue();
3044 if (!
C.Op0.hasOneUse() ||
3051 unsigned NumBits =
Load->getMemoryVT().getSizeInBits();
3052 if ((NumBits != 8 && NumBits != 16) ||
3053 NumBits !=
Load->getMemoryVT().getStoreSizeInBits())
3059 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
3062 uint64_t Mask = (1 << NumBits) - 1;
3065 int64_t SignedValue = ConstOp1->getSExtValue();
3072 }
else if (NumBits == 8) {
3098 if (
C.Op0.getValueType() != MVT::i32 ||
3099 Load->getExtensionType() != ExtType) {
3101 Load->getBasePtr(),
Load->getPointerInfo(),
3102 Load->getMemoryVT(),
Load->getAlign(),
3103 Load->getMemOperand()->getFlags());
3109 if (
C.Op1.getValueType() != MVT::i32 ||
3110 Value != ConstOp1->getZExtValue())
3120 if (
Load->getMemoryVT() == MVT::i8)
3123 switch (
Load->getExtensionType()) {
3141 if (
C.Op0.isMachineOpcode() &&
3142 (
C.Op0.getMachineOpcode() == SystemZ::LOAD_STACK_GUARD))
3146 if (
C.Op0.getValueType() == MVT::i128)
3148 if (
C.Op0.getValueType() == MVT::f128)
3160 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3189 unsigned Opcode0 =
C.Op0.getOpcode();
3196 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3211 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3212 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3234 if (
C1 &&
C1->isZero()) {
3253 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3256 if (
C1 &&
C1->getZExtValue() == 32) {
3257 SDValue ShlOp0 =
C.Op0.getOperand(0);
3276 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3279 C.Op1->getAsZExtVal() == 0) {
3281 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3282 C.Op0.getValueSizeInBits().getFixedValue()) {
3283 unsigned Type = L->getExtensionType();
3286 C.Op0 =
C.Op0.getOperand(0);
3302 if (
C.Opcode != SystemZISD::ICMP)
3312 if (!
C.Op1.isMachineOpcode() ||
3313 C.Op1.getMachineOpcode() != SystemZ::LOAD_STACK_GUARD)
3318 C.Opcode = SystemZISD::CMP_STACKGUARD;
3329 uint64_t Amount = Shift->getZExtValue();
3330 if (Amount >=
N.getValueSizeInBits())
3345 unsigned ICmpType) {
3346 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3368 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3374 if (EffectivelyUnsigned && CmpVal <
Low) {
3382 if (CmpVal == Mask) {
3388 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3394 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3402 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3408 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3437 if (
C.Op0.getValueType() == MVT::i128) {
3443 if (Mask && Mask->getAPIntValue() == 0) {
3444 C.Opcode = SystemZISD::VTM;
3461 uint64_t CmpVal = ConstOp1->getZExtValue();
3468 NewC.Op0 =
C.Op0.getOperand(0);
3469 NewC.Op1 =
C.Op0.getOperand(1);
3473 MaskVal = Mask->getZExtValue();
3493 MaskVal = -(CmpVal & -CmpVal);
3502 unsigned NewCCMask, ShiftVal;
3506 (MaskVal >> ShiftVal != 0) &&
3507 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3509 MaskVal >> ShiftVal,
3513 MaskVal >>= ShiftVal;
3517 (MaskVal << ShiftVal != 0) &&
3518 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3520 MaskVal << ShiftVal,
3524 MaskVal <<= ShiftVal;
3533 C.Opcode = SystemZISD::TM;
3535 if (Mask && Mask->getZExtValue() == MaskVal)
3540 C.CCMask = NewCCMask;
3546 if (
C.Opcode != SystemZISD::ICMP)
3548 if (
C.Op0.getValueType() != MVT::i128)
3559 Src = Src.getOperand(0);
3562 unsigned Opcode = 0;
3563 if (Src.hasOneUse()) {
3564 switch (Src.getOpcode()) {
3565 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3566 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3567 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3568 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3569 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3570 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3576 C.Op0 = Src->getOperand(0);
3577 C.Op1 = Src->getOperand(1);
3581 C.CCMask ^=
C.CCValid;
3593 C.Opcode = SystemZISD::VICMPES;
3605 bool Swap =
false, Invert =
false;
3617 C.Opcode = SystemZISD::UCMP128HI;
3619 C.Opcode = SystemZISD::SCMP128HI;
3624 C.CCMask ^=
C.CCValid;
3635 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3638 if ((~
Known.Zero).getZExtValue() & ~Mask->getZExtValue())
3641 C.Op0 =
C.Op0.getOperand(0);
3653 C.CCValid = CCValid;
3656 C.CCMask =
CC < 4 ? 1 << (3 -
CC) : 0;
3659 C.CCMask =
CC < 4 ? ~(1 << (3 -
CC)) : -1;
3663 C.CCMask =
CC < 4 ? ~0U << (4 -
CC) : -1;
3666 C.CCMask =
CC < 4 ? ~(~0U << (4 -
CC)) : 0;
3670 C.CCMask =
CC < 4 ? ~0U << (3 -
CC) : -1;
3673 C.CCMask =
CC < 4 ? ~(~0U << (3 -
CC)) : 0;
3676 C.CCMask &= CCValid;
3684 bool IsSignaling =
false) {
3687 unsigned Opcode, CCValid;
3699 Comparison
C(CmpOp0, CmpOp1, Chain);
3701 if (
C.Op0.getValueType().isFloatingPoint()) {
3704 C.Opcode = SystemZISD::FCMP;
3705 else if (!IsSignaling)
3706 C.Opcode = SystemZISD::STRICT_FCMP;
3708 C.Opcode = SystemZISD::STRICT_FCMPS;
3713 C.Opcode = SystemZISD::ICMP;
3749 if (!
C.Op1.getNode()) {
3750 if (
C.Opcode == SystemZISD::CMP_STACKGUARD)
3751 return DAG.
getNode(SystemZISD::CMP_STACKGUARD,
DL, MVT::i32,
C.Op0);
3753 switch (
C.Op0.getOpcode()) {
3764 if (
C.Opcode == SystemZISD::ICMP)
3765 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3767 if (
C.Opcode == SystemZISD::TM) {
3770 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3773 if (
C.Opcode == SystemZISD::VICMPES ||
3774 C.Opcode == SystemZISD::VICMPHS ||
3775 C.Opcode == SystemZISD::VICMPHLS ||
3776 C.Opcode == SystemZISD::VFCMPES ||
3777 C.Opcode == SystemZISD::VFCMPHS ||
3778 C.Opcode == SystemZISD::VFCMPHES) {
3779 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3786 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3788 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3797 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3798 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3823 unsigned CCValid,
unsigned CCMask) {
3828 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3906 int Mask[] = { Start, -1, Start + 1, -1 };
3910 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3912 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3926 !Subtarget.hasVectorEnhancements1()) {
3932 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3945 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3948 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3949 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3951 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3964 bool IsSignaling)
const {
3967 assert (!IsSignaling || Chain);
3970 bool Invert =
false;
3978 assert(IsFP &&
"Unexpected integer comparison");
3980 DL, VT, CmpOp1, CmpOp0, Chain);
3982 DL, VT, CmpOp0, CmpOp1, Chain);
3986 LT.getValue(1),
GE.getValue(1));
3995 assert(IsFP &&
"Unexpected integer comparison");
3997 DL, VT, CmpOp1, CmpOp0, Chain);
3999 DL, VT, CmpOp0, CmpOp1, Chain);
4003 LT.getValue(1),
GT.getValue(1));
4024 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
4028 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
4033 Chain =
Cmp.getValue(1);
4041 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
4054 EVT VT =
Op.getValueType();
4056 return lowerVectorSETCC(DAG,
DL, VT,
CC, CmpOp0, CmpOp1);
4065 bool IsSignaling)
const {
4071 EVT VT =
Op.getNode()->getValueType(0);
4073 SDValue Res = lowerVectorSETCC(DAG,
DL, VT,
CC, CmpOp0, CmpOp1,
4074 Chain, IsSignaling);
4096 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
4130 C.CCMask ^=
C.CCValid;
4138 Op = SystemZISD::VICMPE;
4142 Op = SystemZISD::VICMPHL;
4144 Op = SystemZISD::VICMPH;
4183 C.Op1->getAsZExtVal() == 0) {
4190 if (Subtarget.hasVectorEnhancements3() &&
4191 C.Opcode == SystemZISD::ICMP &&
4192 C.Op0.getValueType() == MVT::i128 &&
4202 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4208 const GlobalValue *GV =
Node->getGlobal();
4214 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4236 }
else if (Subtarget.isTargetELF()) {
4241 }
else if (Subtarget.isTargetzOS()) {
4272 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4277 Ops.push_back(Chain);
4279 Node->getValueType(0),
4288 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4289 const uint32_t *
Mask =
4291 assert(Mask &&
"Missing call preserved mask for calling convention");
4295 Ops.push_back(Glue);
4298 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4306SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4330 const GlobalValue *GV =
Node->getGlobal();
4338 SDValue TP = lowerThreadPointer(
DL, DAG);
4345 SystemZConstantPoolValue *CPV =
4354 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4360 SystemZConstantPoolValue *CPV =
4369 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4374 SystemZMachineFunctionInfo* MFI =
4403 SystemZConstantPoolValue *CPV =
4437 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4454 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4459 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4461 MachineFrameInfo &MFI = MF.getFrameInfo();
4465 unsigned Depth =
Op.getConstantOperandVal(0);
4472 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4477 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4483 MachinePointerInfo());
4498 unsigned Depth =
Op.getConstantOperandVal(0);
4503 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4506 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4507 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4508 int Offset = TFL->getReturnAddressOffset(MF);
4512 MachinePointerInfo());
4517 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4519 &SystemZ::GR64BitRegClass);
4527 EVT InVT =
In.getValueType();
4528 EVT ResVT =
Op.getValueType();
4536 LoadN->getBasePtr(), LoadN->getMemOperand());
4542 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4544 if (Subtarget.hasHighWord()) {
4548 MVT::i64,
SDValue(U64, 0), In);
4556 DL, MVT::f32, Out64);
4558 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4561 MVT::f64,
SDValue(U64, 0), In);
4563 if (Subtarget.hasHighWord())
4576 if (Subtarget.isTargetXPLINK64())
4577 return lowerVASTART_XPLINK(
Op, DAG);
4579 return lowerVASTART_ELF(
Op, DAG);
4585 SystemZMachineFunctionInfo *FuncInfo =
4586 MF.
getInfo<SystemZMachineFunctionInfo>();
4596 MachinePointerInfo(SV));
4602 SystemZMachineFunctionInfo *FuncInfo =
4603 MF.
getInfo<SystemZMachineFunctionInfo>();
4612 const unsigned NumFields = 4;
4623 for (
unsigned I = 0;
I < NumFields; ++
I) {
4628 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4629 MachinePointerInfo(SV,
Offset));
4649 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4650 MachinePointerInfo(SrcSV));
4654SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4656 if (Subtarget.isTargetXPLINK64())
4657 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4659 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4663SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4665 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4675 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4678 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4679 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4685 if (ExtraAlignSpace)
4689 bool IsSigned =
false;
4690 bool DoesNotReturn =
false;
4691 bool IsReturnValueUsed =
false;
4692 EVT VT =
Op.getValueType();
4702 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4714 if (ExtraAlignSpace) {
4726SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4728 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4731 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4740 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4743 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4744 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4755 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4756 MachinePointerInfo());
4759 if (ExtraAlignSpace)
4766 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4767 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4783 if (RequiredAlign > StackAlign) {
4793 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4794 MachinePointerInfo());
4800SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4804 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4809 unsigned Opcode)
const {
4810 EVT VT =
Op.getValueType();
4816 assert(Subtarget.hasMiscellaneousExtensions2());
4821 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4827 EVT VT =
Op.getValueType();
4835 else if (Subtarget.hasMiscellaneousExtensions2())
4840 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4875 EVT VT =
Op.getValueType();
4888 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4896 EVT VT =
Op.getValueType();
4916 EVT VT =
Op.getValueType();
4923 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4928 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4938 Known[1].Zero.getZExtValue() };
4940 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4942 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4979 MVT::i64, HighOp, Low32);
4985 SDNode *
N =
Op.getNode();
4990 if (
N->getValueType(0) == MVT::i128) {
4991 unsigned BaseOp = 0;
4992 unsigned FlagOp = 0;
4993 bool IsBorrow =
false;
4994 switch (
Op.getOpcode()) {
4998 FlagOp = SystemZISD::VACC;
5002 FlagOp = SystemZISD::VSCBI;
5017 unsigned BaseOp = 0;
5018 unsigned CCValid = 0;
5019 unsigned CCMask = 0;
5021 switch (
Op.getOpcode()) {
5024 BaseOp = SystemZISD::SADDO;
5029 BaseOp = SystemZISD::SSUBO;
5034 BaseOp = SystemZISD::UADDO;
5039 BaseOp = SystemZISD::USUBO;
5045 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
5049 if (
N->getValueType(1) == MVT::i1)
5075 SDNode *
N =
Op.getNode();
5076 MVT VT =
N->getSimpleValueType(0);
5087 if (VT == MVT::i128) {
5088 unsigned BaseOp = 0;
5089 unsigned FlagOp = 0;
5090 bool IsBorrow =
false;
5091 switch (
Op.getOpcode()) {
5094 BaseOp = SystemZISD::VAC;
5095 FlagOp = SystemZISD::VACCC;
5098 BaseOp = SystemZISD::VSBI;
5099 FlagOp = SystemZISD::VSBCBI;
5118 unsigned BaseOp = 0;
5119 unsigned CCValid = 0;
5120 unsigned CCMask = 0;
5122 switch (
Op.getOpcode()) {
5128 BaseOp = SystemZISD::ADDCARRY;
5136 BaseOp = SystemZISD::SUBCARRY;
5147 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5151 if (
N->getValueType(1) == MVT::i1)
5159 EVT VT =
Op.getValueType();
5161 Op =
Op.getOperand(0);
5184 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5196 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5210 if (NumSignificantBits == 0)
5216 BitSize = std::min(BitSize, OrigBitSize);
5225 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5227 if (BitSize != OrigBitSize)
5264 EVT RegVT =
Op.getValueType();
5266 return lowerATOMIC_LDST_I128(
Op, DAG);
5267 return lowerLoadF16(
Op, DAG);
5273 if (
Node->getMemoryVT().getSizeInBits() == 128)
5274 return lowerATOMIC_LDST_I128(
Op, DAG);
5275 return lowerStoreF16(
Op, DAG);
5282 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5283 "Only custom lowering i128 or f128.");
5296 EVT WideVT = MVT::i32;
5317void SystemZTargetLowering::lowerATOMIC_LOAD_OP(
5319 unsigned Opcode)
const {
5322 EVT NarrowVT =
Node->getMemoryVT();
5323 EVT WideVT = MVT::i32;
5328 MachineMemOperand *MMO =
Node->getMemOperand();
5332 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5334 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5338 SDValue AlignedAddr, BitShift, NegBitShift;
5347 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5350 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5351 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5356 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5357 SDValue Ops[] = { ChainIn, AlignedAddr,
Src2, BitShift, NegBitShift,
5376 EVT MemVT =
Node->getMemoryVT();
5377 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5378 assert(Subtarget.hasInterlockedAccess1() &&
5379 "Should have been expanded by AtomicExpand pass.");
5385 Node->getBasePtr(), NegSrc2,
Node->getMemOperand());
5396 MachineMemOperand *MMO =
Node->getMemOperand();
5399 if (
Node->getMemoryVT() == MVT::i128) {
5408 EVT NarrowVT =
Node->getMemoryVT();
5409 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5410 if (NarrowVT == WideVT) {
5411 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5412 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5414 DL, Tys,
Ops, NarrowVT, MMO);
5428 SDValue AlignedAddr, BitShift, NegBitShift;
5432 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5433 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5436 VTList,
Ops, NarrowVT, MMO);
5450SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5473 auto *Regs = Subtarget.getSpecialRegisters();
5476 "in GHC calling convention");
5478 Regs->getStackPointerRegister(),
Op.getValueType());
5484 auto *Regs = Subtarget.getSpecialRegisters();
5485 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5489 "in GHC calling convention");
5496 if (StoreBackchain) {
5498 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5499 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5500 MachinePointerInfo());
5503 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5506 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5507 MachinePointerInfo());
5514 bool IsData =
Op.getConstantOperandVal(4);
5517 return Op.getOperand(0);
5520 bool IsWrite =
Op.getConstantOperandVal(2);
5527 Node->getMemoryVT(),
Node->getMemOperand());
5531SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5533 unsigned Opcode, CCValid;
5535 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5546SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5548 unsigned Opcode, CCValid;
5551 if (
Op->getNumValues() == 1)
5553 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5558 unsigned Id =
Op.getConstantOperandVal(0);
5560 case Intrinsic::thread_pointer:
5561 return lowerThreadPointer(SDLoc(
Op), DAG);
5563 case Intrinsic::s390_vpdi:
5564 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5565 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5567 case Intrinsic::s390_vperm:
5568 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5569 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5571 case Intrinsic::s390_vuphb:
5572 case Intrinsic::s390_vuphh:
5573 case Intrinsic::s390_vuphf:
5574 case Intrinsic::s390_vuphg:
5575 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5578 case Intrinsic::s390_vuplhb:
5579 case Intrinsic::s390_vuplhh:
5580 case Intrinsic::s390_vuplhf:
5581 case Intrinsic::s390_vuplhg:
5582 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5585 case Intrinsic::s390_vuplb:
5586 case Intrinsic::s390_vuplhw:
5587 case Intrinsic::s390_vuplf:
5588 case Intrinsic::s390_vuplg:
5589 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5592 case Intrinsic::s390_vupllb:
5593 case Intrinsic::s390_vupllh:
5594 case Intrinsic::s390_vupllf:
5595 case Intrinsic::s390_vupllg:
5596 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5599 case Intrinsic::s390_vsumb:
5600 case Intrinsic::s390_vsumh:
5601 case Intrinsic::s390_vsumgh:
5602 case Intrinsic::s390_vsumgf:
5603 case Intrinsic::s390_vsumqf:
5604 case Intrinsic::s390_vsumqg:
5605 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5606 Op.getOperand(1),
Op.getOperand(2));
5608 case Intrinsic::s390_vaq:
5610 Op.getOperand(1),
Op.getOperand(2));
5611 case Intrinsic::s390_vaccb:
5612 case Intrinsic::s390_vacch:
5613 case Intrinsic::s390_vaccf:
5614 case Intrinsic::s390_vaccg:
5615 case Intrinsic::s390_vaccq:
5616 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5617 Op.getOperand(1),
Op.getOperand(2));
5618 case Intrinsic::s390_vacq:
5619 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5620 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5621 case Intrinsic::s390_vacccq:
5622 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5623 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5625 case Intrinsic::s390_vsq:
5627 Op.getOperand(1),
Op.getOperand(2));
5628 case Intrinsic::s390_vscbib:
5629 case Intrinsic::s390_vscbih:
5630 case Intrinsic::s390_vscbif:
5631 case Intrinsic::s390_vscbig:
5632 case Intrinsic::s390_vscbiq:
5633 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5634 Op.getOperand(1),
Op.getOperand(2));
5635 case Intrinsic::s390_vsbiq:
5636 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5637 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5638 case Intrinsic::s390_vsbcbiq:
5639 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5640 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5642 case Intrinsic::s390_vmhb:
5643 case Intrinsic::s390_vmhh:
5644 case Intrinsic::s390_vmhf:
5645 case Intrinsic::s390_vmhg:
5646 case Intrinsic::s390_vmhq:
5648 Op.getOperand(1),
Op.getOperand(2));
5649 case Intrinsic::s390_vmlhb:
5650 case Intrinsic::s390_vmlhh:
5651 case Intrinsic::s390_vmlhf:
5652 case Intrinsic::s390_vmlhg:
5653 case Intrinsic::s390_vmlhq:
5655 Op.getOperand(1),
Op.getOperand(2));
5657 case Intrinsic::s390_vmahb:
5658 case Intrinsic::s390_vmahh:
5659 case Intrinsic::s390_vmahf:
5660 case Intrinsic::s390_vmahg:
5661 case Intrinsic::s390_vmahq:
5662 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5663 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5664 case Intrinsic::s390_vmalhb:
5665 case Intrinsic::s390_vmalhh:
5666 case Intrinsic::s390_vmalhf:
5667 case Intrinsic::s390_vmalhg:
5668 case Intrinsic::s390_vmalhq:
5669 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5670 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5672 case Intrinsic::s390_vmeb:
5673 case Intrinsic::s390_vmeh:
5674 case Intrinsic::s390_vmef:
5675 case Intrinsic::s390_vmeg:
5676 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5677 Op.getOperand(1),
Op.getOperand(2));
5678 case Intrinsic::s390_vmleb:
5679 case Intrinsic::s390_vmleh:
5680 case Intrinsic::s390_vmlef:
5681 case Intrinsic::s390_vmleg:
5682 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5683 Op.getOperand(1),
Op.getOperand(2));
5684 case Intrinsic::s390_vmob:
5685 case Intrinsic::s390_vmoh:
5686 case Intrinsic::s390_vmof:
5687 case Intrinsic::s390_vmog:
5688 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5689 Op.getOperand(1),
Op.getOperand(2));
5690 case Intrinsic::s390_vmlob:
5691 case Intrinsic::s390_vmloh:
5692 case Intrinsic::s390_vmlof:
5693 case Intrinsic::s390_vmlog:
5694 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5695 Op.getOperand(1),
Op.getOperand(2));
5697 case Intrinsic::s390_vmaeb:
5698 case Intrinsic::s390_vmaeh:
5699 case Intrinsic::s390_vmaef:
5700 case Intrinsic::s390_vmaeg:
5702 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5703 Op.getOperand(1),
Op.getOperand(2)),
5705 case Intrinsic::s390_vmaleb:
5706 case Intrinsic::s390_vmaleh:
5707 case Intrinsic::s390_vmalef:
5708 case Intrinsic::s390_vmaleg:
5710 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5711 Op.getOperand(1),
Op.getOperand(2)),
5713 case Intrinsic::s390_vmaob:
5714 case Intrinsic::s390_vmaoh:
5715 case Intrinsic::s390_vmaof:
5716 case Intrinsic::s390_vmaog:
5718 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5719 Op.getOperand(1),
Op.getOperand(2)),
5721 case Intrinsic::s390_vmalob:
5722 case Intrinsic::s390_vmaloh:
5723 case Intrinsic::s390_vmalof:
5724 case Intrinsic::s390_vmalog:
5726 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5727 Op.getOperand(1),
Op.getOperand(2)),
5748 { SystemZISD::MERGE_HIGH, 8,
5749 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5751 { SystemZISD::MERGE_HIGH, 4,
5752 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5754 { SystemZISD::MERGE_HIGH, 2,
5755 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5757 { SystemZISD::MERGE_HIGH, 1,
5758 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5760 { SystemZISD::MERGE_LOW, 8,
5761 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5763 { SystemZISD::MERGE_LOW, 4,
5764 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5766 { SystemZISD::MERGE_LOW, 2,
5767 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5769 { SystemZISD::MERGE_LOW, 1,
5770 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5772 { SystemZISD::PACK, 4,
5773 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5775 { SystemZISD::PACK, 2,
5776 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5778 { SystemZISD::PACK, 1,
5779 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5781 { SystemZISD::PERMUTE_DWORDS, 4,
5782 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5784 { SystemZISD::PERMUTE_DWORDS, 1,
5785 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5799 OpNo0 = OpNo1 = OpNos[1];
5800 }
else if (OpNos[1] < 0) {
5801 OpNo0 = OpNo1 = OpNos[0];
5819 unsigned &OpNo0,
unsigned &OpNo1) {
5820 int OpNos[] = { -1, -1 };
5833 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5835 OpNos[ModelOpNo] = RealOpNo;
5843 unsigned &OpNo0,
unsigned &OpNo1) {
5860 int Elt = Bytes[From];
5863 Transform[From] = -1;
5865 while (
P.Bytes[To] != Elt) {
5870 Transform[From] = To;
5894 Bytes.
resize(NumElements * BytesPerElement, -1);
5895 for (
unsigned I = 0;
I < NumElements; ++
I) {
5896 int Index = VSN->getMaskElt(
I);
5898 for (
unsigned J = 0; J < BytesPerElement; ++J)
5899 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5903 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5906 Bytes.
resize(NumElements * BytesPerElement, -1);
5907 for (
unsigned I = 0;
I < NumElements; ++
I)
5908 for (
unsigned J = 0; J < BytesPerElement; ++J)
5909 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5920 unsigned BytesPerElement,
int &
Base) {
5922 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5923 if (Bytes[Start +
I] >= 0) {
5924 unsigned Elem = Bytes[Start +
I];
5928 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5930 }
else if (
unsigned(
Base) != Elem -
I)
5943 unsigned &StartIndex,
unsigned &OpNo0,
5945 int OpNos[] = { -1, -1 };
5947 for (
unsigned I = 0;
I < 16; ++
I) {
5948 int Index = Bytes[
I];
5954 Shift = ExpectedShift;
5955 else if (Shift != ExpectedShift)
5959 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5961 OpNos[ModelOpNo] = RealOpNo;
5974 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5975 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5983 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5985 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5986 }
else if (
P.Opcode == SystemZISD::PACK) {
5989 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5998 N =
N->getOperand(0);
6001 return Op->getZExtValue() == 0;
6007 for (
unsigned I = 0;
I < Num ;
I++)
6019 for (
unsigned I = 0;
I < 2; ++
I)
6023 unsigned StartIndex, OpNo0, OpNo1;
6025 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
6032 if (ZeroVecIdx != UINT32_MAX) {
6033 bool MaskFirst =
true;
6038 if (OpNo == ZeroVecIdx &&
I == 0) {
6043 if (OpNo != ZeroVecIdx && Byte == 0) {
6050 if (ZeroIdx != -1) {
6053 if (Bytes[
I] >= 0) {
6056 if (OpNo == ZeroVecIdx)
6068 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
6071 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
6083 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
6089struct GeneralShuffle {
6090 GeneralShuffle(EVT vt)
6091 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
6095 void tryPrepareForUnpack();
6096 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
6111 unsigned UnpackFromEltSize;
6118void GeneralShuffle::addUndef() {
6120 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6121 Bytes.push_back(-1);
6130bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6136 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6141 if (FromBytesPerElement < BytesPerElement)
6145 (FromBytesPerElement - BytesPerElement));
6148 while (
Op.getNode()) {
6150 Op =
Op.getOperand(0);
6166 }
else if (
Op.isUndef()) {
6175 for (; OpNo <
Ops.size(); ++OpNo)
6176 if (
Ops[OpNo] ==
Op)
6178 if (OpNo ==
Ops.size())
6183 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6184 Bytes.push_back(
Base +
I);
6193 if (
Ops.size() == 0)
6197 tryPrepareForUnpack();
6200 if (
Ops.size() == 1)
6212 unsigned Stride = 1;
6213 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6214 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6224 else if (OpNo ==
I + Stride)
6235 if (NewBytes[J] >= 0) {
6237 "Invalid double permute");
6240 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6246 if (NewBytes[J] >= 0)
6262 unsigned OpNo0, OpNo1;
6266 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6271 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6278 dbgs() <<
Msg.c_str() <<
" { ";
6279 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6280 dbgs() << Bytes[
I] <<
" ";
6288void GeneralShuffle::tryPrepareForUnpack() {
6290 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6295 if (
Ops.size() > 2 &&
6300 UnpackFromEltSize = 1;
6301 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6302 bool MatchUnpack =
true;
6305 unsigned ToEltSize = UnpackFromEltSize * 2;
6306 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6309 if (Bytes[Elt] != -1) {
6311 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6312 MatchUnpack =
false;
6318 if (
Ops.size() == 2) {
6320 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6322 if (SrcBytes[i] == -1)
6324 if (SrcBytes[i] % 16 !=
int(i))
6325 CanUseUnpackHigh =
false;
6327 CanUseUnpackLow =
false;
6328 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6329 UnpackFromEltSize = UINT_MAX;
6333 if (!CanUseUnpackHigh)
6339 if (UnpackFromEltSize > 4)
6342 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6343 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6345 dumpBytes(Bytes,
"Original Bytes vector:"););
6354 Elt += UnpackFromEltSize;
6355 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6356 Bytes[
B] = Bytes[Elt];
6364 Ops.erase(&
Ops[ZeroVecOpNo]);
6366 if (Bytes[
I] >= 0) {
6368 if (OpNo > ZeroVecOpNo)
6379 if (!unpackWasPrepared())
6381 unsigned InBits = UnpackFromEltSize * 8;
6385 unsigned OutBits = InBits * 2;
6388 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6389 : SystemZISD::UNPACKL_HIGH,
6390 DL, OutVT, PackedOp);
6395 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6396 if (!
Op.getOperand(
I).isUndef())
6412 if (
Value.isUndef())
6424 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6427 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6428 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6449 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6465 GeneralShuffle GS(VT);
6467 bool FoundOne =
false;
6468 for (
unsigned I = 0;
I < NumElements; ++
I) {
6471 Op =
Op.getOperand(0);
6474 unsigned Elem =
Op.getConstantOperandVal(1);
6475 if (!GS.add(
Op.getOperand(0), Elem))
6478 }
else if (
Op.isUndef()) {
6492 if (!ResidueOps.
empty()) {
6493 while (ResidueOps.
size() < NumElements)
6495 for (
auto &
Op : GS.Ops) {
6496 if (!
Op.getNode()) {
6502 return GS.getNode(DAG,
SDLoc(BVN));
6505bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6511 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6522 "Handling full vectors only.");
6542 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6554 unsigned int NumElements = Elems.
size();
6555 unsigned int Count = 0;
6556 for (
auto Elem : Elems) {
6557 if (!Elem.isUndef()) {
6560 else if (Elem !=
Single) {
6584 bool AllLoads =
true;
6585 for (
auto Elem : Elems)
6586 if (!isVectorElementLoad(Elem)) {
6592 if (VT == MVT::v2i64 && !AllLoads)
6596 if (VT == MVT::v2f64 && !AllLoads)
6606 if (VT == MVT::v4f32 && !AllLoads)
6610 if (VT == MVT::v8f16 && !AllLoads) {
6619 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6628 unsigned NumConstants = 0;
6629 for (
unsigned I = 0;
I < NumElements; ++
I) {
6643 if (NumConstants > 0) {
6644 for (
unsigned I = 0;
I < NumElements; ++
I)
6655 std::map<const SDNode*, unsigned> UseCounts;
6656 SDNode *LoadMaxUses =
nullptr;
6657 for (
unsigned I = 0;
I < NumElements; ++
I)
6658 if (isVectorElementLoad(Elems[
I])) {
6659 SDNode *Ld = Elems[
I].getNode();
6660 unsigned Count = ++UseCounts[Ld];
6661 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6664 if (LoadMaxUses !=
nullptr) {
6665 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6669 unsigned I1 = NumElements / 2 - 1;
6670 unsigned I2 = NumElements - 1;
6671 bool Def1 = !Elems[
I1].isUndef();
6672 bool Def2 = !Elems[I2].isUndef();
6686 for (
unsigned I = 0;
I < NumElements; ++
I)
6687 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6697 EVT VT =
Op.getValueType();
6699 if (BVN->isConstant()) {
6700 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6718 for (
unsigned I = 0;
I < NumElements; ++
I)
6720 return buildVector(DAG,
DL, VT,
Ops);
6727 EVT VT =
Op.getValueType();
6730 if (VSN->isSplat()) {
6732 unsigned Index = VSN->getSplatIndex();
6734 "Splat index should be defined and in first operand");
6740 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6744 GeneralShuffle
GS(VT);
6745 for (
unsigned I = 0;
I < NumElements; ++
I) {
6746 int Elt = VSN->getMaskElt(
I);
6749 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6750 unsigned(Elt) % NumElements))
6753 return GS.getNode(DAG, SDLoc(VSN));
6768 assert(
Op.getSimpleValueType() == MVT::i64 &&
6769 "Expexted to convert i64 to f16.");
6781 assert(
Op.getSimpleValueType() == MVT::f16 &&
6782 "Expected to convert f16 to i64.");
6804 EVT VT =
Op.getValueType();
6807 if (!Subtarget.hasVector())
6832SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6838 EVT VT =
Op.getValueType();
6845 if (!Subtarget.hasVector())
6851 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6859SDValue SystemZTargetLowering::
6862 EVT OutVT =
Op.getValueType();
6866 unsigned StartOffset = 0;
6873 ArrayRef<int> ShuffleMask = SVN->
getMask();
6878 if (ToBits == 64 && OutNumElts == 2) {
6879 int NumElem = ToBits / FromBits;
6880 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6886 int StartOffsetCandidate = -1;
6887 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6888 if (ShuffleMask[Elt] == -1)
6890 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6891 if (StartOffsetCandidate == -1)
6892 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6893 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6896 StartOffsetCandidate = -1;
6899 if (StartOffsetCandidate != -1) {
6900 StartOffset = StartOffsetCandidate;
6909 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6910 if (StartOffset >= OutNumElts) {
6911 Opcode = SystemZISD::UNPACK_LOW;
6912 StartOffset -= OutNumElts;
6914 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6915 }
while (FromBits != ToBits);
6920SDValue SystemZTargetLowering::
6924 EVT OutVT =
Op.getValueType();
6928 unsigned NumInPerOut = InNumElts / OutNumElts;
6933 SmallVector<int, 16>
Mask(InNumElts);
6934 unsigned ZeroVecElt = InNumElts;
6935 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6936 unsigned MaskElt = PackedElt * NumInPerOut;
6937 unsigned End = MaskElt + NumInPerOut - 1;
6938 for (; MaskElt <
End; MaskElt++)
6939 Mask[MaskElt] = ZeroVecElt++;
6940 Mask[MaskElt] = PackedElt;
6947 unsigned ByScalar)
const {
6952 EVT VT =
Op.getValueType();
6957 APInt SplatBits, SplatUndef;
6958 unsigned SplatBitSize;
6962 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6963 ElemBitSize,
true) &&
6964 SplatBitSize == ElemBitSize) {
6967 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6970 BitVector UndefElements;
6976 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6983 if (VSN->isSplat()) {
6984 SDValue VSNOp0 = VSN->getOperand(0);
6985 unsigned Index = VSN->getSplatIndex();
6987 "Splat index should be defined and in first operand");
6994 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
7012 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
7013 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
7016 if (ShiftAmt > 120) {
7020 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
7024 SmallVector<int, 16>
Mask(16);
7025 for (
unsigned Elt = 0; Elt < 16; Elt++)
7026 Mask[Elt] = (ShiftAmt >> 3) + Elt;
7028 if ((ShiftAmt & 7) == 0)
7032 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
7050 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
7051 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
7054 if (ShiftAmt > 120) {
7058 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
7062 SmallVector<int, 16>
Mask(16);
7063 for (
unsigned Elt = 0; Elt < 16; Elt++)
7064 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
7066 if ((ShiftAmt & 7) == 0)
7070 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
7082 MVT DstVT =
Op.getSimpleValueType();
7085 unsigned SrcAS =
N->getSrcAddressSpace();
7087 assert(SrcAS !=
N->getDestAddressSpace() &&
7088 "addrspacecast must be between different address spaces");
7096 }
else if (DstVT == MVT::i32) {
7110 if (
In.getSimpleValueType() != MVT::f16)
7117 SDValue Chain,
bool IsStrict)
const {
7118 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
7121 std::tie(Result, Chain) =
7130 bool IsStrict =
Op->isStrictFPOpcode();
7132 MVT VT =
Op.getSimpleValueType();
7133 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7141 if (!
Subtarget.hasFPExtension() && !IsSigned)
7152 if (VT == MVT::i128) {
7155 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7165 bool IsStrict =
Op->isStrictFPOpcode();
7167 MVT VT =
Op.getSimpleValueType();
7168 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7173 if (VT == MVT::f16) {
7180 if (!Subtarget.hasFPExtension() && !IsSigned)
7183 if (InVT == MVT::i128) {
7186 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7195 EVT RegVT =
Op.getValueType();
7196 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7203 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7205 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7206 AtomicLd->getMemOperand());
7209 assert(EVT(RegVT) == Ld->getMemoryVT() &&
"Unhandled f16 load");
7211 Ld->getBasePtr(), Ld->getPointerInfo(), MVT::i16,
7212 Ld->getBaseAlign(), Ld->getMemOperand()->getFlags());
7226 Shft, AtomicSt->getBasePtr(),
7227 AtomicSt->getMemOperand());
7230 return DAG.
getTruncStore(St->getChain(),
DL, Shft, St->getBasePtr(), MVT::i16,
7231 St->getMemOperand());
7237 MVT ResultVT =
Op.getSimpleValueType();
7239 unsigned Check =
Op.getConstantOperandVal(1);
7241 unsigned TDCMask = 0;
7276 MachinePointerInfo MPI =
7282 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7286 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7291 switch (
Op.getOpcode()) {
7293 return lowerFRAMEADDR(
Op, DAG);
7295 return lowerRETURNADDR(
Op, DAG);
7297 return lowerBR_CC(
Op, DAG);
7299 return lowerSELECT_CC(
Op, DAG);
7301 return lowerSETCC(
Op, DAG);
7303 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7305 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7317 return lowerBITCAST(
Op, DAG);
7319 return lowerVASTART(
Op, DAG);
7321 return lowerVACOPY(
Op, DAG);
7323 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7325 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7327 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7329 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7331 return lowerSMUL_LOHI(
Op, DAG);
7333 return lowerUMUL_LOHI(
Op, DAG);
7335 return lowerSDIVREM(
Op, DAG);
7337 return lowerUDIVREM(
Op, DAG);
7342 return lowerXALUO(
Op, DAG);
7345 return lowerUADDSUBO_CARRY(
Op, DAG);
7347 return lowerOR(
Op, DAG);
7349 return lowerCTPOP(
Op, DAG);
7351 return lowerVECREDUCE_ADD(
Op, DAG);
7353 return lowerATOMIC_FENCE(
Op, DAG);
7355 return lowerATOMIC_STORE(
Op, DAG);
7357 return lowerATOMIC_LOAD(
Op, DAG);
7359 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7361 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7363 return lowerSTACKSAVE(
Op, DAG);
7365 return lowerSTACKRESTORE(
Op, DAG);
7367 return lowerPREFETCH(
Op, DAG);
7369 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7371 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7373 return lowerBUILD_VECTOR(
Op, DAG);
7375 return lowerVECTOR_SHUFFLE(
Op, DAG);
7377 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7379 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7381 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7383 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7385 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7387 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7389 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7391 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7395 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7397 return lowerFSHL(
Op, DAG);
7399 return lowerFSHR(
Op, DAG);
7402 return lowerFP_EXTEND(
Op, DAG);
7407 return lower_FP_TO_INT(
Op, DAG);
7412 return lower_INT_TO_FP(
Op, DAG);
7414 return lowerLoadF16(
Op, DAG);
7416 return lowerStoreF16(
Op, DAG);
7418 return lowerIS_FPCLASS(
Op, DAG);
7420 return lowerGET_ROUNDING(
Op, DAG);
7422 return lowerREADCYCLECOUNTER(
Op, DAG);
7444 &SystemZ::FP128BitRegClass);
7453 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7468 &SystemZ::FP128BitRegClass);
7485 switch (
N->getOpcode()) {
7489 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7492 DL, Tys,
Ops, MVT::i128, MMO);
7495 if (
N->getValueType(0) == MVT::f128)
7509 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7512 DL, Tys,
Ops, MVT::i128, MMO);
7518 MVT::Other, Res), 0);
7530 DL, Tys,
Ops, MVT::i128, MMO);
7544 EVT SrcVT = Src.getValueType();
7545 EVT ResVT =
N->getValueType(0);
7546 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7548 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7549 if (Subtarget.hasVector()) {
7557 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7559 Subtarget.hasVector()
7573 bool IsStrict =
N->isStrictFPOpcode();
7575 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7576 EVT ResVT =
N->getValueType(0);
7578 if (ResVT == MVT::f16) {
7601 bool IsStrict =
N->isStrictFPOpcode();
7603 EVT ResVT =
N->getValueType(0);
7604 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7607 if (InVT == MVT::f16) {
7613 std::tie(InF32, Chain) =
7625 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_SWAPW);
7628 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7631 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_SUB);
7634 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_AND);
7637 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_OR);
7640 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7643 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7646 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7649 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7652 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7655 lowerATOMIC_LOAD_OP(
N,
Results, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7671bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7686 DAGCombinerInfo &DCI,
7694 unsigned Opcode =
Op.getOpcode();
7697 Op =
Op.getOperand(0);
7699 canTreatAsByteVector(
Op.getValueType())) {
7708 BytesPerElement,
First))
7715 if (Byte % BytesPerElement != 0)
7718 Index = Byte / BytesPerElement;
7722 canTreatAsByteVector(
Op.getValueType())) {
7725 EVT OpVT =
Op.getValueType();
7727 if (OpBytesPerElement < BytesPerElement)
7731 unsigned End = (
Index + 1) * BytesPerElement;
7732 if (
End % OpBytesPerElement != 0)
7735 Op =
Op.getOperand(
End / OpBytesPerElement - 1);
7739 if (!
Op.getValueType().isInteger()) {
7744 DCI.AddToWorklist(
Op.getNode());
7747 if (ResIntVT != ResVT) {
7748 DCI.AddToWorklist(
Op.getNode());
7755 canTreatAsByteVector(
Op.getValueType()) &&
7756 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7758 EVT ExtVT =
Op.getValueType();
7759 EVT OpVT =
Op.getOperand(0).getValueType();
7762 unsigned Byte =
Index * BytesPerElement;
7763 unsigned SubByte =
Byte % ExtBytesPerElement;
7764 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7765 if (SubByte < MinSubByte ||
7766 SubByte + BytesPerElement > ExtBytesPerElement)
7769 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7771 Byte += SubByte - MinSubByte;
7772 if (Byte % BytesPerElement != 0)
7774 Op =
Op.getOperand(0);
7781 if (
Op.getValueType() != VecVT) {
7783 DCI.AddToWorklist(
Op.getNode());
7793SDValue SystemZTargetLowering::combineTruncateExtract(
7802 if (canTreatAsByteVector(VecVT)) {
7806 if (BytesPerElement % TruncBytes == 0) {
7812 unsigned Scale = BytesPerElement / TruncBytes;
7813 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7820 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7821 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7829SDValue SystemZTargetLowering::combineZERO_EXTEND(
7830 SDNode *
N, DAGCombinerInfo &DCI)
const {
7832 SelectionDAG &DAG = DCI.DAG;
7834 EVT VT =
N->getValueType(0);
7835 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7838 if (TrueOp && FalseOp) {
7848 DCI.CombineTo(N0.
getNode(), TruncSelect);
7891 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7909SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7910 SDNode *
N, DAGCombinerInfo &DCI)
const {
7914 SelectionDAG &DAG = DCI.DAG;
7916 EVT VT =
N->getValueType(0);
7930SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7931 SDNode *
N, DAGCombinerInfo &DCI)
const {
7935 SelectionDAG &DAG = DCI.DAG;
7937 EVT VT =
N->getValueType(0);
7944 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7945 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7961SDValue SystemZTargetLowering::combineMERGE(
7962 SDNode *
N, DAGCombinerInfo &DCI)
const {
7963 SelectionDAG &DAG = DCI.DAG;
7964 unsigned Opcode =
N->getOpcode();
7972 if (Op1 ==
N->getOperand(0))
7977 if (ElemBytes <= 4) {
7978 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7979 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7985 DCI.AddToWorklist(Op1.
getNode());
7988 DCI.AddToWorklist(
Op.getNode());
7997 LoPart = HiPart =
nullptr;
8002 if (
Use.getResNo() != 0)
8007 bool IsLoPart =
true;
8032 LoPart = HiPart =
nullptr;
8037 if (
Use.getResNo() != 0)
8043 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
8046 switch (
User->getConstantOperandVal(1)) {
8047 case SystemZ::subreg_l64:
8052 case SystemZ::subreg_h64:
8064SDValue SystemZTargetLowering::combineLOAD(
8065 SDNode *
N, DAGCombinerInfo &DCI)
const {
8066 SelectionDAG &DAG = DCI.DAG;
8067 EVT LdVT =
N->getValueType(0);
8071 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
8072 if (PtrVT != LoadNodeVT) {
8076 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
8077 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
8078 LN->getMemOperand());
8088 SDNode *LoPart, *HiPart;
8096 LD->getPointerInfo(),
LD->getBaseAlign(),
8097 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8099 DCI.CombineTo(HiPart, EltLoad,
true);
8106 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
8107 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
8109 DCI.CombineTo(LoPart, EltLoad,
true);
8116 DCI.AddToWorklist(Chain.
getNode());
8131 for (SDUse &Use :
N->uses()) {
8132 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
8136 }
else if (
Use.getResNo() == 0)
8139 if (!Replicate || OtherUses.
empty())
8145 for (SDNode *U : OtherUses) {
8148 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8154bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8155 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8157 if (Subtarget.hasVectorEnhancements2())
8158 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8170 for (
unsigned i = 0; i < NumElts; ++i) {
8171 if (M[i] < 0)
continue;
8172 if ((
unsigned) M[i] != NumElts - 1 - i)
8180 for (
auto *U : StoredVal->
users()) {
8182 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8241SDValue SystemZTargetLowering::combineSTORE(
8242 SDNode *
N, DAGCombinerInfo &DCI)
const {
8243 SelectionDAG &DAG = DCI.DAG;
8246 EVT MemVT = SN->getMemoryVT();
8250 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8251 if (PtrVT != StoreNodeVT) {
8255 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8256 SN->getPointerInfo(), SN->getBaseAlign(),
8257 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8265 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8267 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8268 DCI.AddToWorklist(
Value.getNode());
8272 SN->getBasePtr(), SN->getMemoryVT(),
8273 SN->getMemOperand());
8284 return DAG.
getNode(SystemZISD::MOV_STACKGUARD, SDLoc(SN), MVT::Other,
Ops);
8288 if (!SN->isTruncatingStore() &&
8304 Ops, MemVT, SN->getMemOperand());
8307 if (!SN->isTruncatingStore() &&
8310 Subtarget.hasVectorEnhancements2()) {
8312 ArrayRef<int> ShuffleMask = SVN->
getMask();
8320 Ops, MemVT, SN->getMemOperand());
8325 if (!SN->isTruncatingStore() &&
8328 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8332 Ops, MemVT, SN->getMemOperand());
8342 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8343 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8345 SN->getChain(),
DL, LoPart,
8347 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8348 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8366 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8368 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8372 APInt Val =
C->getAPIntValue();
8375 assert(SN->isTruncatingStore() &&
8376 "Non-truncating store and immediate value does not fit?");
8377 Val = Val.
trunc(TotBytes * 8);
8380 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8381 if (VCI.isVectorConstantLegal(Subtarget) &&
8382 VCI.Opcode == SystemZISD::REPLICATE) {
8390 auto FindReplicatedReg = [&](
SDValue MulOp) {
8391 EVT MulVT = MulOp.getValueType();
8392 if (MulOp->getOpcode() ==
ISD::MUL &&
8393 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8397 WordVT =
LHS->getOperand(0).getValueType();
8404 SystemZVectorConstantInfo VCI(
8406 if (VCI.isVectorConstantLegal(Subtarget) &&
8407 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8408 WordVT == VCI.VecVT.getScalarType())
8420 FindReplicatedReg(SplatVal);
8425 FindReplicatedReg(Op1);
8430 "Bad type handling");
8434 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8435 SN->getBasePtr(), SN->getMemOperand());
8442SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8443 SDNode *
N, DAGCombinerInfo &DCI)
const {
8444 SelectionDAG &DAG = DCI.DAG;
8447 N->getOperand(0).hasOneUse() &&
8448 Subtarget.hasVectorEnhancements2()) {
8450 ArrayRef<int> ShuffleMask = SVN->
getMask();
8463 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8467 DCI.CombineTo(
N, ESLoad);
8471 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8481SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8482 SDNode *
N, DAGCombinerInfo &DCI)
const {
8483 SelectionDAG &DAG = DCI.DAG;
8485 if (!Subtarget.hasVector())
8491 Op.getValueType().isVector() &&
8492 Op.getOperand(0).getValueType().isVector() &&
8493 Op.getValueType().getVectorNumElements() ==
8494 Op.getOperand(0).getValueType().getVectorNumElements())
8495 Op =
Op.getOperand(0);
8499 EVT VecVT =
Op.getValueType();
8502 Op.getOperand(0),
N->getOperand(1));
8503 DCI.AddToWorklist(
Op.getNode());
8505 if (EltVT !=
N->getValueType(0)) {
8506 DCI.AddToWorklist(
Op.getNode());
8516 if (canTreatAsByteVector(VecVT))
8517 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8518 IndexN->getZExtValue(), DCI,
false);
8523SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8524 SDNode *
N, DAGCombinerInfo &DCI)
const {
8525 SelectionDAG &DAG = DCI.DAG;
8527 if (
N->getOperand(0) ==
N->getOperand(1))
8528 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8538 if (Chain1 == Chain2)
8546SDValue SystemZTargetLowering::combineFP_ROUND(
8547 SDNode *
N, DAGCombinerInfo &DCI)
const {
8549 if (!Subtarget.hasVector())
8558 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8559 SelectionDAG &DAG = DCI.DAG;
8561 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8567 for (
auto *U : Vec->
users()) {
8568 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8570 U->getOperand(0) == Vec &&
8572 U->getConstantOperandVal(1) == 1) {
8574 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8578 if (
N->isStrictFPOpcode()) {
8582 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8583 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8586 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8588 DCI.AddToWorklist(VRound.
getNode());
8592 DCI.AddToWorklist(Extract1.
getNode());
8598 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8601 N->getVTList(), Extract0, Chain);
8610SDValue SystemZTargetLowering::combineFP_EXTEND(
8611 SDNode *
N, DAGCombinerInfo &DCI)
const {
8613 if (!Subtarget.hasVector())
8622 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8623 SelectionDAG &DAG = DCI.DAG;
8625 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8631 for (
auto *U : Vec->
users()) {
8632 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8634 U->getOperand(0) == Vec &&
8636 U->getConstantOperandVal(1) == 2) {
8638 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8642 if (
N->isStrictFPOpcode()) {
8646 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8647 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8650 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8652 DCI.AddToWorklist(VExtend.
getNode());
8656 DCI.AddToWorklist(Extract1.
getNode());
8662 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8665 N->getVTList(), Extract0, Chain);
8674SDValue SystemZTargetLowering::combineINT_TO_FP(
8675 SDNode *
N, DAGCombinerInfo &DCI)
const {
8678 SelectionDAG &DAG = DCI.DAG;
8680 unsigned Opcode =
N->getOpcode();
8681 EVT OutVT =
N->getValueType(0);
8685 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8691 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8692 OutScalarBits <= 64) {
8696 unsigned ExtOpcode =
8699 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8704SDValue SystemZTargetLowering::combineFCOPYSIGN(
8705 SDNode *
N, DAGCombinerInfo &DCI)
const {
8706 SelectionDAG &DAG = DCI.DAG;
8707 EVT VT =
N->getValueType(0);
8720SDValue SystemZTargetLowering::combineBSWAP(
8721 SDNode *
N, DAGCombinerInfo &DCI)
const {
8722 SelectionDAG &DAG = DCI.DAG;
8725 N->getOperand(0).hasOneUse() &&
8726 canLoadStoreByteSwapped(
N->getValueType(0))) {
8735 EVT LoadVT =
N->getValueType(0);
8736 if (LoadVT == MVT::i16)
8741 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8745 if (
N->getValueType(0) == MVT::i16)
8750 DCI.CombineTo(
N, ResVal);
8754 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8763 Op.getValueType().isVector() &&
8764 Op.getOperand(0).getValueType().isVector() &&
8765 Op.getValueType().getVectorNumElements() ==
8766 Op.getOperand(0).getValueType().getVectorNumElements())
8767 Op =
Op.getOperand(0);
8779 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8781 EVT VecVT =
N->getValueType(0);
8785 DCI.AddToWorklist(Vec.
getNode());
8789 DCI.AddToWorklist(Elt.
getNode());
8792 DCI.AddToWorklist(Vec.
getNode());
8794 DCI.AddToWorklist(Elt.
getNode());
8802 if (SV &&
Op.hasOneUse()) {
8810 EVT VecVT =
N->getValueType(0);
8813 DCI.AddToWorklist(Op0.
getNode());
8817 DCI.AddToWorklist(Op1.
getNode());
8820 DCI.AddToWorklist(Op0.
getNode());
8822 DCI.AddToWorklist(Op1.
getNode());
8830SDValue SystemZTargetLowering::combineSETCC(
8831 SDNode *
N, DAGCombinerInfo &DCI)
const {
8832 SelectionDAG &DAG = DCI.DAG;
8838 EVT VT =
N->getValueType(0);
8848 Src.getValueType().isFixedLengthVector() &&
8849 Src.getValueType().getScalarType() == MVT::i1) {
8850 EVT CmpVT = Src.getOperand(0).getValueType();
8867 unsigned Depth = 0) {
8875 case SystemZISD::IPM:
8880 case SystemZISD::SELECT_CCMASK: {
8882 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8883 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8886 return std::make_pair(OpCC, OpCCValid);
8891 int CCValidVal = CCValid->getZExtValue();
8892 return std::make_pair(Op4CCReg, CCValidVal);
8903 return std::make_pair(Op0CC, Op0CCValid);
8919 return {Val, Val, Val, Val};
8920 case SystemZISD::IPM: {
8925 for (
auto CC : {0, 1, 2, 3})
8928 return ShiftedCCVals;
8930 case SystemZISD::SELECT_CCMASK: {
8934 if (!CCValid || !CCMask)
8937 int CCValidVal = CCValid->getZExtValue();
8938 int CCMaskVal = CCMask->getZExtValue();
8948 if (TrueSDVals.empty() || FalseSDVals.empty())
8951 for (
auto &CCVal : {0, 1, 2, 3})
8952 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8954 : FalseSDVals[CCVal]);
8955 return MergedSDVals;
8972 if (Op0SDVals.empty() || Op1SDVals.empty())
8975 for (
auto CCVal : {0, 1, 2, 3})
8977 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8978 return BinaryOpSDVals;
8989 auto *CCNode = CCReg.
getNode();
8993 if (CCNode->getOpcode() == SystemZISD::TM) {
8996 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8999 if (!Op0Node || !Op1Node)
9001 auto Op0APVal = Op0Node->getAPIntValue();
9002 auto Op1APVal = Op1Node->getAPIntValue();
9003 auto Result = Op0APVal & Op1APVal;
9004 bool AllOnes = Result == Op1APVal;
9005 bool AllZeros = Result == 0;
9006 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits() - 1] != 0;
9007 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
9011 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
9016 if (Op0SDVals.empty() || Op1SDVals.empty())
9019 for (
auto CC : {0, 1, 2, 3}) {
9020 auto CCVal = emulateTMCCMask(Op0SDVals[
CC], Op1SDVals[
CC]);
9024 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
9026 NewCCMask &= Op0CCValid;
9029 CCValid = Op0CCValid;
9032 if (CCNode->getOpcode() != SystemZISD::ICMP ||
9039 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
9043 if (Op0SDVals.empty() || Op1SDVals.empty())
9047 auto CmpTypeVal = CmpType->getZExtValue();
9048 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
9052 if (!Op0Node || !Op1Node)
9054 auto Op0APVal = Op0Node->getAPIntValue();
9055 auto Op1APVal = Op1Node->getAPIntValue();
9057 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
9058 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
9061 for (
auto CC : {0, 1, 2, 3}) {
9062 auto CCVal = compareCCSigned(Op0SDVals[
CC], Op1SDVals[
CC]);
9066 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
9068 NewCCMask &= Op0CCValid;
9071 CCValid = Op0CCValid;
9084 const auto isFlagOutOpCC = [](
const Value *V) {
9086 const Value *RHSVal;
9093 if (CB->isInlineAsm()) {
9095 return IA && IA->getConstraintString().contains(
"{@cc}");
9106 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
9109 return {-1, -1, -1};
9113 DAGCombinerInfo &DCI)
const {
9119 if (!CCValid || !CCMask)
9122 int CCValidVal = CCValid->getZExtValue();
9123 int CCMaskVal = CCMask->getZExtValue();
9130 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
9131 CCMaskVal != CCValidVal)
9132 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
9136 N->getOperand(3), CCReg);
9140SDValue SystemZTargetLowering::combineSELECT_CCMASK(
9141 SDNode *
N, DAGCombinerInfo &DCI)
const {
9147 if (!CCValid || !CCMask)
9150 int CCValidVal = CCValid->getZExtValue();
9151 int CCMaskVal = CCMask->getZExtValue();
9154 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
9158 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
9159 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9161 if (Val.getOperand(4) != CCReg)
9168 int CCMaskVal = CCMask->getZExtValue();
9169 for (
auto &
CC : {0, 1, 2, 3})
9184 if (TrueSDVals.empty())
9185 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9186 if (FalseSDVals.empty())
9187 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9188 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9189 SmallSet<SDValue, 4> MergedSDValsSet;
9191 for (
auto CC : {0, 1, 2, 3}) {
9192 if ((CCValidVal & ((1 << (3 -
CC)))) != 0)
9193 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 -
CC))) != 0)
9197 if (MergedSDValsSet.
size() == 1)
9198 return *MergedSDValsSet.
begin();
9199 if (MergedSDValsSet.
size() == 2) {
9200 auto BeginIt = MergedSDValsSet.
begin();
9201 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9202 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9205 for (
auto CC : {0, 1, 2, 3}) {
9207 NewCCMask |= ((CCMaskVal & (1 << (3 -
CC))) != 0)
9208 ? (TrueSDVals[
CC] == NewTrueVal)
9209 : (FalseSDVals[
CC] == NewTrueVal);
9211 CCMaskVal = NewCCMask;
9212 CCMaskVal &= CCValidVal;
9215 IsCombinedCCReg =
true;
9223 if (CCMaskVal == CCValidVal)
9226 if (IsCombinedCCReg)
9228 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9235SDValue SystemZTargetLowering::combineGET_CCMASK(
9236 SDNode *
N, DAGCombinerInfo &DCI)
const {
9241 if (!CCValid || !CCMask)
9243 int CCValidVal = CCValid->getZExtValue();
9244 int CCMaskVal = CCMask->getZExtValue();
9249 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9254 if (!SelectCCValid || !SelectCCMask)
9256 int SelectCCValidVal = SelectCCValid->getZExtValue();
9257 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9261 if (!TrueVal || !FalseVal)
9265 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9266 SelectCCMaskVal ^= SelectCCValidVal;
9270 if (SelectCCValidVal & ~CCValidVal)
9272 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9275 return Select->getOperand(4);
9278SDValue SystemZTargetLowering::combineIntDIVREM(
9279 SDNode *
N, DAGCombinerInfo &DCI)
const {
9280 SelectionDAG &DAG = DCI.DAG;
9281 EVT VT =
N->getValueType(0);
9298SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9299 SDNode *
N, DAGCombinerInfo &DCI)
const {
9300 SelectionDAG &DAG = DCI.DAG;
9304 "SRL or SRA node is required here!");
9306 if (!Subtarget.hasVector())
9316 SDValue ShiftOperand =
N->getOperand(0);
9336 if (!IsSignExt && !IsZeroExt)
9344 unsigned ActiveBits = IsSignExt
9345 ?
Constant->getAPIntValue().getSignificantBits()
9346 :
Constant->getAPIntValue().getActiveBits();
9347 if (ActiveBits > NarrowVTSize)
9363 unsigned ActiveBits = IsSignExt
9364 ?
Constant->getAPIntValue().getSignificantBits()
9365 :
Constant->getAPIntValue().getActiveBits();
9366 if (ActiveBits > NarrowVTSize)
9383 "Cannot have a multiply node with two different operand types.");
9385 "Cannot have an add node with two different operand types.");
9396 if (ShiftAmt != NarrowVTSize)
9400 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9401 NarrowVT == MVT::v4i32 ||
9402 (Subtarget.hasVectorEnhancements3() &&
9403 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9409 MulhRightOp, MulhAddOp);
9410 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9421 EVT VT =
Op.getValueType();
9430 Op =
Op.getOperand(0);
9431 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9435 bool CanUseEven =
true, CanUseOdd =
true;
9436 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9437 if (ShuffleMask[Elt] == -1)
9439 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9441 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9444 Op =
Op.getOperand(0);
9446 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9448 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9454 if (VT == MVT::i128 &&
Subtarget.hasVectorEnhancements3() &&
9458 Op =
Op.getOperand(0);
9460 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9462 unsigned Elem =
Op.getConstantOperandVal(1);
9463 Op =
Op.getOperand(0);
9465 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9467 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9474SDValue SystemZTargetLowering::combineMUL(
9475 SDNode *
N, DAGCombinerInfo &DCI)
const {
9476 SelectionDAG &DAG = DCI.DAG;
9483 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9484 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9489SDValue SystemZTargetLowering::combineINTRINSIC(
9490 SDNode *
N, DAGCombinerInfo &DCI)
const {
9491 SelectionDAG &DAG = DCI.DAG;
9493 unsigned Id =
N->getConstantOperandVal(1);
9497 case Intrinsic::s390_vll:
9498 case Intrinsic::s390_vlrl:
9500 if (
C->getZExtValue() >= 15)
9501 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9502 N->getOperand(3), MachinePointerInfo());
9505 case Intrinsic::s390_vstl:
9506 case Intrinsic::s390_vstrl:
9508 if (
C->getZExtValue() >= 15)
9509 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9510 N->getOperand(4), MachinePointerInfo());
9518 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9525 switch(
N->getOpcode()) {
9530 case SystemZISD::MERGE_HIGH:
9531 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9536 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9546 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9547 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9550 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9551 case ISD::MUL:
return combineMUL(
N, DCI);
9555 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9567 EVT VT =
Op.getValueType();
9570 unsigned Opcode =
Op.getOpcode();
9572 unsigned Id =
Op.getConstantOperandVal(0);
9574 case Intrinsic::s390_vpksh:
9575 case Intrinsic::s390_vpksf:
9576 case Intrinsic::s390_vpksg:
9577 case Intrinsic::s390_vpkshs:
9578 case Intrinsic::s390_vpksfs:
9579 case Intrinsic::s390_vpksgs:
9580 case Intrinsic::s390_vpklsh:
9581 case Intrinsic::s390_vpklsf:
9582 case Intrinsic::s390_vpklsg:
9583 case Intrinsic::s390_vpklshs:
9584 case Intrinsic::s390_vpklsfs:
9585 case Intrinsic::s390_vpklsgs:
9587 SrcDemE = DemandedElts;
9590 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9593 case Intrinsic::s390_vuphb:
9594 case Intrinsic::s390_vuphh:
9595 case Intrinsic::s390_vuphf:
9596 case Intrinsic::s390_vuplhb:
9597 case Intrinsic::s390_vuplhh:
9598 case Intrinsic::s390_vuplhf:
9599 SrcDemE =
APInt(NumElts * 2, 0);
9602 case Intrinsic::s390_vuplb:
9603 case Intrinsic::s390_vuplhw:
9604 case Intrinsic::s390_vuplf:
9605 case Intrinsic::s390_vupllb:
9606 case Intrinsic::s390_vupllh:
9607 case Intrinsic::s390_vupllf:
9608 SrcDemE =
APInt(NumElts * 2, 0);
9611 case Intrinsic::s390_vpdi: {
9613 SrcDemE =
APInt(NumElts, 0);
9614 if (!DemandedElts[OpNo - 1])
9616 unsigned Mask =
Op.getConstantOperandVal(3);
9617 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9619 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9622 case Intrinsic::s390_vsldb: {
9624 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9625 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9626 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9627 unsigned NumSrc0Els = 16 - FirstIdx;
9628 SrcDemE =
APInt(NumElts, 0);
9630 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9633 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9638 case Intrinsic::s390_vperm:
9647 case SystemZISD::JOIN_DWORDS:
9649 SrcDemE =
APInt(1, 1);
9651 case SystemZISD::SELECT_CCMASK:
9652 SrcDemE = DemandedElts;
9663 const APInt &DemandedElts,
9678 const APInt &DemandedElts,
9680 unsigned Depth)
const {
9684 unsigned Tmp0, Tmp1;
9686 Known.Zero.setBitsFrom(2);
9689 [[maybe_unused]]
EVT VT =
Op.getValueType();
9690 if (
Op.getResNo() != 0)
9693 "KnownBits does not match VT in bitwidth");
9696 "DemandedElts does not match VT number of elements");
9698 unsigned Opcode =
Op.getOpcode();
9700 bool IsLogical =
false;
9701 unsigned Id =
Op.getConstantOperandVal(0);
9703 case Intrinsic::s390_vpksh:
9704 case Intrinsic::s390_vpksf:
9705 case Intrinsic::s390_vpksg:
9706 case Intrinsic::s390_vpkshs:
9707 case Intrinsic::s390_vpksfs:
9708 case Intrinsic::s390_vpksgs:
9709 case Intrinsic::s390_vpklsh:
9710 case Intrinsic::s390_vpklsf:
9711 case Intrinsic::s390_vpklsg:
9712 case Intrinsic::s390_vpklshs:
9713 case Intrinsic::s390_vpklsfs:
9714 case Intrinsic::s390_vpklsgs:
9715 case Intrinsic::s390_vpdi:
9716 case Intrinsic::s390_vsldb:
9717 case Intrinsic::s390_vperm:
9720 case Intrinsic::s390_vuplhb:
9721 case Intrinsic::s390_vuplhh:
9722 case Intrinsic::s390_vuplhf:
9723 case Intrinsic::s390_vupllb:
9724 case Intrinsic::s390_vupllh:
9725 case Intrinsic::s390_vupllf:
9728 case Intrinsic::s390_vuphb:
9729 case Intrinsic::s390_vuphh:
9730 case Intrinsic::s390_vuphf:
9731 case Intrinsic::s390_vuplb:
9732 case Intrinsic::s390_vuplhw:
9733 case Intrinsic::s390_vuplf: {
9748 case SystemZISD::JOIN_DWORDS:
9749 case SystemZISD::SELECT_CCMASK:
9752 case SystemZISD::REPLICATE: {
9775 if (
LHS == 1)
return 1;
9778 if (
RHS == 1)
return 1;
9779 unsigned Common = std::min(
LHS,
RHS);
9780 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9781 EVT VT =
Op.getValueType();
9783 if (SrcBitWidth > VTBits) {
9784 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9785 if (Common > SrcExtraBits)
9786 return (Common - SrcExtraBits);
9789 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9796 unsigned Depth)
const {
9797 if (
Op.getResNo() != 0)
9799 unsigned Opcode =
Op.getOpcode();
9801 unsigned Id =
Op.getConstantOperandVal(0);
9803 case Intrinsic::s390_vpksh:
9804 case Intrinsic::s390_vpksf:
9805 case Intrinsic::s390_vpksg:
9806 case Intrinsic::s390_vpkshs:
9807 case Intrinsic::s390_vpksfs:
9808 case Intrinsic::s390_vpksgs:
9809 case Intrinsic::s390_vpklsh:
9810 case Intrinsic::s390_vpklsf:
9811 case Intrinsic::s390_vpklsg:
9812 case Intrinsic::s390_vpklshs:
9813 case Intrinsic::s390_vpklsfs:
9814 case Intrinsic::s390_vpklsgs:
9815 case Intrinsic::s390_vpdi:
9816 case Intrinsic::s390_vsldb:
9817 case Intrinsic::s390_vperm:
9819 case Intrinsic::s390_vuphb:
9820 case Intrinsic::s390_vuphh:
9821 case Intrinsic::s390_vuphf:
9822 case Intrinsic::s390_vuplb:
9823 case Intrinsic::s390_vuplhw:
9824 case Intrinsic::s390_vuplf: {
9828 EVT VT =
Op.getValueType();
9838 case SystemZISD::SELECT_CCMASK:
9851 switch (
Op->getOpcode()) {
9852 case SystemZISD::PCREL_WRAPPER:
9853 case SystemZISD::PCREL_OFFSET:
9864 "Unexpected stack alignment");
9867 unsigned StackProbeSize =
9870 StackProbeSize &= ~(StackAlign - 1);
9871 return StackProbeSize ? StackProbeSize : StackAlign;
9888 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9894 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9910 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9912 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9918 if (miI ==
MBB->end()) {
9920 if (Succ->isLiveIn(SystemZ::CC))
9931 switch (
MI.getOpcode()) {
9932 case SystemZ::Select32:
9933 case SystemZ::Select64:
9934 case SystemZ::Select128:
9935 case SystemZ::SelectF32:
9936 case SystemZ::SelectF64:
9937 case SystemZ::SelectF128:
9938 case SystemZ::SelectVR32:
9939 case SystemZ::SelectVR64:
9940 case SystemZ::SelectVR128:
9972 for (
auto *
MI : Selects) {
9973 Register DestReg =
MI->getOperand(0).getReg();
9974 Register TrueReg =
MI->getOperand(1).getReg();
9975 Register FalseReg =
MI->getOperand(2).getReg();
9980 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9983 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9984 TrueReg = It->second.first;
9986 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9987 FalseReg = It->second.second;
9990 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9995 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
10006 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
10007 assert(TFL->hasReservedCallFrame(MF) &&
10008 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
10013 uint32_t NumBytes =
MI.getOperand(0).getImm();
10018 MI.eraseFromParent();
10027 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10029 unsigned CCValid =
MI.getOperand(3).getImm();
10030 unsigned CCMask =
MI.getOperand(4).getImm();
10035 SmallVector<MachineInstr*, 8> Selects;
10036 SmallVector<MachineInstr*, 8> DbgValues;
10038 unsigned Count = 0;
10042 assert(NextMI.getOperand(3).getImm() == CCValid &&
10043 "Bad CCValid operands since CC was not redefined.");
10044 if (NextMI.getOperand(4).getImm() == CCMask ||
10045 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
10051 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
10052 NextMI.usesCustomInsertionHook())
10055 for (
auto *SelMI : Selects)
10056 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
10060 if (NextMI.isDebugInstr()) {
10062 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
10065 }
else if (User || ++
Count > 20)
10069 MachineInstr *LastMI = Selects.back();
10070 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
10072 MachineBasicBlock *StartMBB =
MBB;
10102 for (
auto *SelMI : Selects)
10103 SelMI->eraseFromParent();
10106 for (
auto *DbgMI : DbgValues)
10107 MBB->
splice(InsertPos, StartMBB, DbgMI);
10118 unsigned StoreOpcode,
10119 unsigned STOCOpcode,
10120 bool Invert)
const {
10121 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10123 Register SrcReg =
MI.getOperand(0).getReg();
10124 MachineOperand
Base =
MI.getOperand(1);
10125 int64_t Disp =
MI.getOperand(2).getImm();
10126 Register IndexReg =
MI.getOperand(3).getReg();
10127 unsigned CCValid =
MI.getOperand(4).getImm();
10128 unsigned CCMask =
MI.getOperand(5).getImm();
10131 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
10135 MachineMemOperand *MMO =
nullptr;
10136 for (
auto *
I :
MI.memoperands())
10137 if (
I->isStore()) {
10145 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
10157 MI.eraseFromParent();
10165 MachineBasicBlock *StartMBB =
MBB;
10171 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10198 MI.eraseFromParent();
10208 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10216 MachineBasicBlock *StartMBB =
MBB;
10234 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10261 MI.eraseFromParent();
10272 bool Invert)
const {
10274 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10281 int64_t Disp =
MI.getOperand(2).getImm();
10283 Register BitShift =
MI.getOperand(4).getReg();
10284 Register NegBitShift =
MI.getOperand(5).getReg();
10285 unsigned BitSize =
MI.getOperand(6).getImm();
10289 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10290 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10291 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10301 MachineBasicBlock *StartMBB =
MBB;
10337 .
addImm(-1U << (32 - BitSize))
10339 }
else if (BinOpcode)
10367 MI.eraseFromParent();
10378 unsigned KeepOldMask)
const {
10380 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10386 int64_t Disp =
MI.getOperand(2).getImm();
10388 Register BitShift =
MI.getOperand(4).getReg();
10389 Register NegBitShift =
MI.getOperand(5).getReg();
10390 unsigned BitSize =
MI.getOperand(6).getImm();
10394 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10395 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10396 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10407 MachineBasicBlock *StartMBB =
MBB;
10475 MI.eraseFromParent();
10485 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10491 int64_t Disp =
MI.getOperand(2).getImm();
10492 Register CmpVal =
MI.getOperand(3).getReg();
10493 Register OrigSwapVal =
MI.getOperand(4).getReg();
10494 Register BitShift =
MI.getOperand(5).getReg();
10495 Register NegBitShift =
MI.getOperand(6).getReg();
10496 int64_t BitSize =
MI.getOperand(7).getImm();
10502 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10503 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10504 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10505 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10517 MachineBasicBlock *StartMBB =
MBB;
10594 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10597 MI.eraseFromParent();
10604 unsigned Opcode,
bool IsMemset)
const {
10606 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10611 uint64_t DestDisp =
MI.getOperand(1).getImm();
10616 auto foldDisplIfNeeded = [&](MachineOperand &
Base,
uint64_t &Disp) ->
void {
10619 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10629 SrcDisp =
MI.getOperand(3).getImm();
10631 SrcBase = DestBase;
10632 SrcDisp = DestDisp++;
10633 foldDisplIfNeeded(DestBase, DestDisp);
10636 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10637 bool IsImmForm = LengthMO.
isImm();
10638 bool IsRegForm = !IsImmForm;
10641 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10643 MachineOperand DBase,
uint64_t DDisp,
10645 unsigned Length) ->
void {
10649 if (ByteMO.
isImm())
10664 bool NeedsLoop =
false;
10666 Register LenAdjReg = SystemZ::NoRegister;
10668 ImmLength = LengthMO.
getImm();
10669 ImmLength += IsMemset ? 2 : 1;
10670 if (ImmLength == 0) {
10671 MI.eraseFromParent();
10674 if (Opcode == SystemZ::CLC) {
10675 if (ImmLength > 3 * 256)
10685 }
else if (ImmLength > 6 * 256)
10693 LenAdjReg = LengthMO.
getReg();
10698 MachineBasicBlock *EndMBB =
10699 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10707 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10717 auto loadZeroAddress = [&]() -> MachineOperand {
10722 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10723 DestBase = loadZeroAddress();
10724 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10725 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10727 MachineBasicBlock *StartMBB =
nullptr;
10728 MachineBasicBlock *LoopMBB =
nullptr;
10729 MachineBasicBlock *NextMBB =
nullptr;
10730 MachineBasicBlock *DoneMBB =
nullptr;
10731 MachineBasicBlock *AllDoneMBB =
nullptr;
10735 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10744 RC = &SystemZ::GR64BitRegClass;
10772 MBB = MemsetOneCheckMBB;
10783 MBB = MemsetOneMBB;
10815 if (EndMBB && !ImmLength)
10837 if (!HaveSingleBase)
10844 if (Opcode == SystemZ::MVC)
10871 if (!HaveSingleBase)
10896 Register RemDestReg = HaveSingleBase ? RemSrcReg
10901 if (!HaveSingleBase)
10909 MachineInstrBuilder EXRL_MIB =
10917 if (Opcode != SystemZ::MVC) {
10927 while (ImmLength > 0) {
10931 foldDisplIfNeeded(DestBase, DestDisp);
10932 foldDisplIfNeeded(SrcBase, SrcDisp);
10933 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10934 DestDisp += ThisLength;
10935 SrcDisp += ThisLength;
10936 ImmLength -= ThisLength;
10939 if (EndMBB && ImmLength > 0) {
10955 MI.eraseFromParent();
10962 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10968 assert(Len > 0 && Len <= 256 &&
"Memmove of of unsupported constant length.");
10997 MI.eraseFromParent();
11006 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11010 uint64_t End1Reg =
MI.getOperand(0).getReg();
11011 uint64_t Start1Reg =
MI.getOperand(1).getReg();
11012 uint64_t Start2Reg =
MI.getOperand(2).getReg();
11013 uint64_t CharReg =
MI.getOperand(3).getReg();
11020 MachineBasicBlock *StartMBB =
MBB;
11056 MI.eraseFromParent();
11063 bool NoFloat)
const {
11065 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
11066 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11069 MI.setDesc(
TII->get(Opcode));
11073 uint64_t Control =
MI.getOperand(2).getImm();
11074 static const unsigned GPRControlBit[16] = {
11075 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
11076 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
11078 Control |= GPRControlBit[15];
11079 if (TFI->
hasFP(MF))
11080 Control |= GPRControlBit[11];
11081 MI.getOperand(2).setImm(Control);
11084 for (
int I = 0;
I < 16;
I++) {
11085 if ((Control & GPRControlBit[
I]) == 0) {
11092 if (!NoFloat && (Control & 4) != 0) {
11093 if (Subtarget.hasVector()) {
11111 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11114 Register SrcReg =
MI.getOperand(0).getReg();
11125 MI.eraseFromParent();
11134 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11137 Register DstReg =
MI.getOperand(0).getReg();
11138 Register SizeReg =
MI.getOperand(2).getReg();
11140 MachineBasicBlock *StartMBB =
MBB;
11227 MI.eraseFromParent();
11231SDValue SystemZTargetLowering::
11234 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11246 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
11251 .
addImm(
MI.getOperand(1).getImm());
11252 MI.eraseFromParent();
11258 switch (
MI.getOpcode()) {
11259 case SystemZ::ADJCALLSTACKDOWN:
11260 case SystemZ::ADJCALLSTACKUP:
11261 return emitAdjCallStack(
MI,
MBB);
11263 case SystemZ::Select32:
11264 case SystemZ::Select64:
11265 case SystemZ::Select128:
11266 case SystemZ::SelectF32:
11267 case SystemZ::SelectF64:
11268 case SystemZ::SelectF128:
11269 case SystemZ::SelectVR32:
11270 case SystemZ::SelectVR64:
11271 case SystemZ::SelectVR128:
11272 return emitSelect(
MI,
MBB);
11274 case SystemZ::CondStore8Mux:
11275 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11276 case SystemZ::CondStore8MuxInv:
11277 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11278 case SystemZ::CondStore16Mux:
11279 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11280 case SystemZ::CondStore16MuxInv:
11281 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11282 case SystemZ::CondStore32Mux:
11283 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11284 case SystemZ::CondStore32MuxInv:
11285 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11286 case SystemZ::CondStore8:
11287 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11288 case SystemZ::CondStore8Inv:
11289 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11290 case SystemZ::CondStore16:
11291 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11292 case SystemZ::CondStore16Inv:
11293 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11294 case SystemZ::CondStore32:
11295 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11296 case SystemZ::CondStore32Inv:
11297 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11298 case SystemZ::CondStore64:
11299 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11300 case SystemZ::CondStore64Inv:
11301 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11302 case SystemZ::CondStoreF32:
11303 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11304 case SystemZ::CondStoreF32Inv:
11305 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11306 case SystemZ::CondStoreF64:
11307 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11308 case SystemZ::CondStoreF64Inv:
11309 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11311 case SystemZ::SCmp128Hi:
11312 return emitICmp128Hi(
MI,
MBB,
false);
11313 case SystemZ::UCmp128Hi:
11314 return emitICmp128Hi(
MI,
MBB,
true);
11317 case SystemZ::ATOMIC_SWAPW:
11318 return emitAtomicLoadBinary(
MI,
MBB, 0);
11320 case SystemZ::ATOMIC_LOADW_AR:
11321 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11322 case SystemZ::ATOMIC_LOADW_AFI:
11323 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11325 case SystemZ::ATOMIC_LOADW_SR:
11326 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11328 case SystemZ::ATOMIC_LOADW_NR:
11329 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11330 case SystemZ::ATOMIC_LOADW_NILH:
11331 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11333 case SystemZ::ATOMIC_LOADW_OR:
11334 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11335 case SystemZ::ATOMIC_LOADW_OILH:
11336 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11338 case SystemZ::ATOMIC_LOADW_XR:
11339 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11340 case SystemZ::ATOMIC_LOADW_XILF:
11341 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11343 case SystemZ::ATOMIC_LOADW_NRi:
11344 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11345 case SystemZ::ATOMIC_LOADW_NILHi:
11346 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11348 case SystemZ::ATOMIC_LOADW_MIN:
11350 case SystemZ::ATOMIC_LOADW_MAX:
11352 case SystemZ::ATOMIC_LOADW_UMIN:
11354 case SystemZ::ATOMIC_LOADW_UMAX:
11357 case SystemZ::ATOMIC_CMP_SWAPW:
11358 return emitAtomicCmpSwapW(
MI,
MBB);
11359 case SystemZ::MVCImm:
11360 case SystemZ::MVCReg:
11361 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11362 case SystemZ::NCImm:
11363 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11364 case SystemZ::OCImm:
11365 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11366 case SystemZ::XCImm:
11367 case SystemZ::XCReg:
11368 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11369 case SystemZ::CLCImm:
11370 case SystemZ::CLCReg:
11371 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11372 case SystemZ::MemsetImmImm:
11373 case SystemZ::MemsetImmReg:
11374 case SystemZ::MemsetRegImm:
11375 case SystemZ::MemsetRegReg:
11376 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11377 case SystemZ::MemmoveImm:
11378 return emitMemmoveImm(
MI,
MBB);
11379 case SystemZ::CLSTLoop:
11380 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11381 case SystemZ::MVSTLoop:
11382 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11383 case SystemZ::SRSTLoop:
11384 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11385 case SystemZ::TBEGIN:
11386 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11387 case SystemZ::TBEGIN_nofloat:
11388 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11389 case SystemZ::TBEGINC:
11390 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11391 case SystemZ::LTEBRCompare_Pseudo:
11392 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11393 case SystemZ::LTDBRCompare_Pseudo:
11394 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11395 case SystemZ::LTXBRCompare_Pseudo:
11396 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11398 case SystemZ::PROBED_ALLOCA:
11399 return emitProbedAlloca(
MI,
MBB);
11400 case SystemZ::EH_SjLj_SetJmp:
11402 case SystemZ::EH_SjLj_LongJmp:
11405 case TargetOpcode::STACKMAP:
11406 case TargetOpcode::PATCHPOINT:
11409 case SystemZ::MOV_STACKGUARD_DAG:
11410 return emitStackGuardPseudo(
MI,
MBB, SystemZ::MOV_STACKGUARD);
11412 case SystemZ::CMP_STACKGUARD_DAG:
11413 return emitStackGuardPseudo(
MI,
MBB, SystemZ::CMP_STACKGUARD);
11442 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11462 EVT VT =
Op.getValueType();
11463 Op =
Op.getOperand(0);
11464 EVT OpVT =
Op.getValueType();
11466 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11498 if (Attrs.hasRetAttrs())
11499 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11500 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11501 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11504 OS << *FT->getParamType(
I);
11506 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11515bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11516 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11517 if (Itr == IsInternalCache.end())
11518 Itr = IsInternalCache
11519 .insert(std::pair<const Function *, bool>(
11522 return Itr->second;
11525bool SystemZTargetLowering::enableNarrowIntArgsVerification()
const {
11526 if (!Subtarget.isTargetELF())
11539void SystemZTargetLowering::verifyNarrowIntegerArgs_Call(
11542 if (!enableNarrowIntArgsVerification())
11544 bool IsInternal =
false;
11545 const Function *CalleeFn =
nullptr;
11548 IsInternal = isInternal(CalleeFn);
11550 if (!verifyNarrowIntegerArgs(C_ABI, Outs, CalleeFn,
false)) {
11551 errs() <<
"Callee: ";
11552 if (CalleeFn !=
nullptr)
11556 errs() <<
"Caller: ";
11559 errs() <<
" " << *CLI.CB;
11562 LLVM_DEBUG(
dbgs() <<
"Outgoing call arguments verified as ABI compliant: ";
11564 else dbgs() <<
"-\n";);
11567void SystemZTargetLowering::verifyNarrowIntegerArgs_Ret(
11570 if (!enableNarrowIntArgsVerification())
11573 if (!verifyNarrowIntegerArgs(C_ABI, Outs,
F,
true)) {
11574 errs() <<
"Returning from function: ";
11578 LLVM_DEBUG(
dbgs() <<
"Return argument verified as ABI compliant : ";
11585bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11587 const Function *FunHeader,
bool IsRet)
const {
11588 if (IsRet && Outs.
size() != 1)
11591 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11592 EVT OrigArgVT = Outs[i].ArgVT;
11595 assert(Outs[i].VT == MVT::i32 &&
"Unexpected integer argument VT.");
11596 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11597 unsigned OrigIdx = Outs[i].OrigArgIndex;
11600 if (C_ABI && !
Flags.isSExt() && !
Flags.isZExt() && !
Flags.isNoExt()) {
11601 errs() <<
"ERROR: (C ABI violation) missing extension attribute on "
11602 << (IsRet ?
"return value" : Twine(
"arg ") + Twine(OrigIdx))
11609 const AttributeList &FunAttrs = FunHeader->
getAttributes();
11610 const AttributeSet
Attrs =
11611 IsRet ? FunAttrs.getRetAttrs() : FunAttrs.getParamAttrs(OrigIdx);
11612 if (
Attrs.hasAttribute(Attribute::SExt) && !
Flags.isSExt()) {
11613 errs() <<
"ERROR: Missing SExt on arg " << OrigIdx <<
".\n";
11616 if (
Attrs.hasAttribute(Attribute::ZExt) && !
Flags.isZExt()) {
11617 errs() <<
"ERROR: Missing ZExt on arg " << OrigIdx <<
".\n";
11628 StringRef GuardMode = M.getStackProtectorGuard();
11631 if (GuardMode ==
"tls" || GuardMode.
empty())
const AArch64Subtarget & Subtarget
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
static bool isZeroVector(SDValue N)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
Function Alias Analysis Results
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isSelectPseudo(MachineInstr &MI)
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
static constexpr MCPhysReg SPReg
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallSet class.
static SDValue getI128Select(SelectionDAG &DAG, const SDLoc &DL, Comparison C, SDValue TrueOp, SDValue FalseOp)
static SmallVector< SDValue, 4 > simplifyAssumingCCVal(SDValue &Val, SDValue &CC, SelectionDAG &DAG)
static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void adjustForLTGFR(Comparison &C)
static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0, SDValue Op1)
static cl::opt< bool > EnableIntArgExtCheck("argext-abi-check", cl::init(false), cl::desc("Verify that narrow int args are properly extended per the " "SystemZ ABI."))
static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG)
static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT, unsigned Opcode, SDValue Op0, SDValue Op1, SDValue &Even, SDValue &Odd)
static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)
static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Value)
static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In)
static bool isSimpleShift(SDValue N, unsigned &ShiftVal)
static SDValue mergeHighParts(SelectionDAG &DAG, const SDLoc &DL, unsigned MergedBits, EVT VT, SDValue Op0, SDValue Op1)
static bool isI128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static bool chooseShuffleOpNos(int *OpNos, unsigned &OpNo0, unsigned &OpNo1)
static uint32_t findZeroVectorIdx(SDValue *Ops, unsigned Num)
static bool isVectorElementSwap(ArrayRef< int > M, EVT VT)
static void getCSAddressAndShifts(SDValue Addr, SelectionDAG &DAG, SDLoc DL, SDValue &AlignedAddr, SDValue &BitShift, SDValue &NegBitShift)
static bool isShlDoublePermute(const SmallVectorImpl< int > &Bytes, unsigned &StartIndex, unsigned &OpNo0, unsigned &OpNo1)
static SDValue getPermuteNode(SelectionDAG &DAG, const SDLoc &DL, const Permute &P, SDValue Op0, SDValue Op1)
static SDNode * emitIntrinsicWithCCAndChain(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static SDValue getCCResult(SelectionDAG &DAG, SDValue CCReg)
static void adjustForStackGuardCompare(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend, SDValue Op0, SDValue Op1, SDValue &Hi, SDValue &Lo)
static bool isF128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static void createPHIsForSelects(SmallVector< MachineInstr *, 8 > &Selects, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, MachineBasicBlock *SinkMBB)
static SDValue getGeneralPermuteNode(SelectionDAG &DAG, const SDLoc &DL, SDValue *Ops, const SmallVectorImpl< int > &Bytes)
static unsigned getVectorComparisonOrInvert(ISD::CondCode CC, CmpMode Mode, bool &Invert)
static unsigned CCMaskForCondCode(ISD::CondCode CC)
static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void adjustForFNeg(Comparison &C)
static bool isScalarToVector(SDValue Op)
static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue CCReg, unsigned CCValid, unsigned CCMask)
static bool matchPermute(const SmallVectorImpl< int > &Bytes, const Permute &P, unsigned &OpNo0, unsigned &OpNo1)
static bool isAddCarryChain(SDValue Carry)
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static MachineOperand earlyUseOperand(MachineOperand Op)
static bool canUseSiblingCall(const CCState &ArgCCInfo, SmallVectorImpl< CCValAssign > &ArgLocs, SmallVectorImpl< ISD::OutputArg > &Outs)
static bool getzOSCalleeAndADA(SelectionDAG &DAG, SDValue &Callee, SDValue &ADA, SDLoc &DL, SDValue &Chain)
static SDValue convertToF16(SDValue Op, SelectionDAG &DAG)
static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask, SelectionDAG &DAG)
static bool shouldSwapCmpOperands(const Comparison &C)
static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType)
static SDValue getADAEntry(SelectionDAG &DAG, SDValue Val, SDLoc DL, unsigned Offset, bool LoadAdr=false)
static SDNode * emitIntrinsicWithCC(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static void adjustForSubtraction(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool getVPermMask(SDValue ShuffleOp, SmallVectorImpl< int > &Bytes)
static const Permute PermuteForms[]
static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static std::pair< SDValue, int > findCCUse(const SDValue &Val, unsigned Depth=0)
static bool isSubBorrowChain(SDValue Carry)
static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool analyzeArgSplit(const SmallVectorImpl< ArgTy > &Args, SmallVector< CCValAssign, 16 > &ArgLocs, unsigned I, MVT &PartVT, unsigned &NumParts)
static bool isInBoundsConstantVectorIndex(EVT VecVT, SDValue Idx)
static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts, unsigned OpNo)
static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op, bool IsNegative)
static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static SDValue expandBitCastI128ToF128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static SDValue tryBuildVectorShuffle(SelectionDAG &DAG, BuildVectorSDNode *BVN)
static SDValue convertFromF16(SDValue Op, SDLoc DL, SelectionDAG &DAG)
static unsigned getVectorComparison(ISD::CondCode CC, CmpMode Mode)
static SDValue lowerGR128ToI128(SelectionDAG &DAG, SDValue In)
static SDValue MergeInputChains(SDNode *N1, SDNode *N2)
static SDValue expandBitCastF128ToI128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, uint64_t Mask, uint64_t CmpVal, unsigned ICmpType)
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL, SDValue Op, SDValue Chain)
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static bool checkCCKill(MachineInstr &MI, MachineBasicBlock *MBB)
static Register forceReg(MachineInstr &MI, MachineOperand &Base, const SystemZInstrInfo *TII)
static bool is32Bit(EVT VT)
static std::pair< unsigned, const TargetRegisterClass * > parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC, const unsigned *Map, unsigned Size)
static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, const SystemZSubtarget &Subtarget, SDValue &Op)
static bool matchDoublePermute(const SmallVectorImpl< int > &Bytes, const Permute &P, SmallVectorImpl< int > &Transform)
static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, SDValue Call, unsigned CCValid, uint64_t CC, ISD::CondCode Cond)
static Register getOrCreateADAVirtualRegister(MachineFunction &MF)
static SDValue buildFPVecFromScalars4(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SmallVectorImpl< SDValue > &Elems, unsigned Pos)
static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg)
static AddressingMode getLoadStoreAddrMode(bool HasVector, Type *Ty)
static void printFunctionArgExts(const Function *F, raw_ostream &OS)
static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Op0, SDValue Op1)
static void computeKnownBitsBinOp(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static bool getShuffleInput(const SmallVectorImpl< int > &Bytes, unsigned Start, unsigned BytesPerElement, int &Base)
static AddressingMode supportedAddressingMode(Instruction *I, bool HasVector)
static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isSingleWord() const
Determine if this APInt just has one word to store value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
LLVM Basic Block Representation.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI bool isConstant() const
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
This class represents a function call, abstracting a target machine's calling convention.
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
const Constant * getConstVal() const
uint64_t getZExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
LLVM_ABI unsigned getPointerSize(unsigned AS=0) const
The pointer representation size in bytes, rounded up to a whole number of bytes.
iterator find(const_arg_type_t< KeyT > Val)
constexpr bool isScalar() const
Exactly one element.
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false, bool IgnoreCastedDirectCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
Tracks which library functions to use for a particular subtarget or function.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
static auto integer_fixedlen_vector_valuetypes()
uint64_t getScalarSizeInBits() const
bool isVector() const
Return true if this is a vector value type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
ElementCount getVectorElementCount() const
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setAdjustsStack(bool V)
void setFrameAddressIsTaken(bool T)
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
reverse_iterator rbegin()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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
ISD::CondCode getOperandCondCode(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getAtomicLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT MemVT, EVT VT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO)
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI bool isConstantIntBuildVectorOrConstantInt(SDValue N, bool AllowOpaques=true) const
Test whether the given value is a constant int or similar node.
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS, const SDNodeFlags Flags=SDNodeFlags())
Return an AddrSpaceCastSDNode.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI std::pair< SDValue, SDValue > getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT)
Convert Op, which must be a STRICT operation of float type, to the float type VT, by either extending...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
ArrayRef< int > getMask() const
const_iterator begin() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A SystemZ-specific class detailing special use registers particular for calling conventions.
virtual int getStackPointerBias()=0
virtual int getReturnFunctionAddressRegister()=0
virtual int getCallFrameSize()=0
virtual int getStackPointerRegister()=0
static SystemZConstantPoolValue * Create(const GlobalValue *GV, SystemZCP::SystemZCPModifier Modifier)
unsigned getVarArgsFrameIndex() const
void setVarArgsFrameIndex(unsigned FI)
void setRegSaveFrameIndex(unsigned FI)
void incNumLocalDynamicTLSAccesses()
Register getVarArgsFirstGPR() const
void setADAVirtualRegister(Register Reg)
void setVarArgsFirstGPR(Register GPR)
Register getADAVirtualRegister() const
void setSizeOfFnParams(unsigned Size)
void setVarArgsFirstFPR(Register FPR)
unsigned getRegSaveFrameIndex() const
Register getVarArgsFirstFPR() const
SystemZCallingConventionRegisters * getSpecialRegisters() const
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be cast by the IR-level AtomicExpand pass.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &, EVT) const override
Return the ValueType of the result of SETCC operations.
bool allowTruncateForTailCall(Type *, Type *) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
SDValue LowerAsmOutputForConstraint(SDValue &Chain, SDValue &Flag, const SDLoc &DL, const AsmOperandInfo &Constraint, SelectionDAG &DAG) const override
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool useSoftFloat() const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
bool canMergeStoresTo(unsigned AS, EVT MemVT, const MachineFunction &MF) const override
Returns if it's reasonable to merge stores to MemVT size.
std::pair< SDValue, SDValue > makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT, ArrayRef< SDValue > Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL, bool DoesNotReturn, bool IsReturnValueUsed) const
void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const override
Insert SSP declaration if global stack protector is used.
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, UndefPoisonKind Kind, unsigned Depth) const override
Return true if this function can prove that Op is never poison and, Kind can be used to track poison ...
SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI)
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns how the legalizer should materialize the specified FP immediate.
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool isTypeDesirableForOp(SDNode *N, EVT VT) const override
Overload that takes the specific node being optimized.
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
SDValue joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, std::optional< CallingConv::ID > CC) const override
Target-specific combining of register parts into its original value.
bool isTruncateFree(Type *, Type *) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg, SDLoc DL, SDValue Chain, bool IsStrict) const
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine the number of bits in the operation that are sign bits.
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool isLegalAddImmediate(int64_t Imm) const override
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
CondMergingParams getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs, const Function *F) const override
TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const override
Return the preferred vector type legalization action.
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
bool aggressivelyPreferBuildVectorSources(EVT VecVT) const override
AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be cast by the IR-level AtomicExpand pass into.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
unsigned getStackProbeSize(const MachineFunction &MF) const
XPLINK64 calling convention specific use registers Particular to z/OS when in 64 bit mode.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
virtual MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
LegalizeTypeAction
This enum indicates whether a types are legal for a target, and if not, what action should be used to...
virtual void insertSSPDeclarations(Module &M, const LibcallLoweringInfo &Libcalls) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
virtual TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(MVT VT) const
Return the preferred vector type legalization action.
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Let target indicate that an extending atomic load of the specified type is legal.
virtual unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
@ Legal
The target can instruction select the immediate natively.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const
Determines the optimal series of memory ops to replace the memset / memcpy.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
virtual bool isTypeDesirableForOp(unsigned, EVT VT) const
Return true if the target has native support for the specified value type and it is 'desirable' to us...
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned VerifyArgABICompliance
When set to true, call/return argument extensions of narrow integers are verified in the target backe...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ POISON
POISON - A poison node.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ PSEUDO_FMIN
PSEUDO_FMIN is strictly equivalent to op0 olt op1 ?
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Same semantics as the llvm.minnum/maxnum intrinsics.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - Same semantics as the llvm.minimum/maximum intrinsics.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ CTTZ_ZERO_POISON
Bit counting operators with a poisoned result for zero inputs.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ FMINIMUMNUM
FMINIMUMNUM/FMAXIMUMNUM - Same semantics as the llvm.minimumnum/maximumnum intrinsics.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are 0 o...
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
auto m_Cmp()
Matches any compare instruction and ignore it.
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ System
Synchronized with respect to all concurrently executing threads.
@ MO_ADA_DATA_SYMBOL_ADDR
@ MO_ADA_DIRECT_FUNC_DESC
@ MO_ADA_INDIRECT_FUNC_DESC
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const int64_t ELFCallFrameSize
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned VR32Regs[32]
unsigned odd128(bool Is32bit)
const unsigned CCMASK_CMP_GE
static bool isImmHH(uint64_t Val)
const unsigned CCMASK_TEND
const unsigned CCMASK_CS_EQ
const unsigned CCMASK_TBEGIN
const MCPhysReg ELFArgFPRs[ELFNumArgFPRs]
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_TM_SOME_1
const unsigned CCMASK_LOGICAL_CARRY
const unsigned TDCMASK_NORMAL_MINUS
const unsigned CCMASK_TDC
const unsigned CCMASK_FCMP
const unsigned CCMASK_TM_SOME_0
static bool isImmHL(uint64_t Val)
const unsigned TDCMASK_SUBNORMAL_MINUS
const unsigned TDCMASK_NORMAL_PLUS
const unsigned CCMASK_CMP_GT
const unsigned TDCMASK_QNAN_MINUS
const unsigned CCMASK_ANY
const unsigned CCMASK_ARITH
const unsigned CCMASK_TM_MIXED_MSB_0
const unsigned TDCMASK_SUBNORMAL_PLUS
static bool isImmLL(uint64_t Val)
const unsigned VectorBits
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned TDCMASK_INFINITY_PLUS
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_TM_ALL_0
const unsigned CCMASK_CMP_LE
const unsigned CCMASK_CMP_O
const unsigned CCMASK_CMP_EQ
const unsigned VectorBytes
const unsigned TDCMASK_INFINITY_MINUS
const unsigned CCMASK_ICMP
const unsigned CCMASK_VCMP_ALL
const unsigned CCMASK_VCMP_NONE
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_VCMP
const unsigned CCMASK_TM_MIXED_MSB_1
const unsigned CCMASK_TM_MSB_0
const unsigned CCMASK_ARITH_OVERFLOW
const unsigned CCMASK_CS_NE
const unsigned TDCMASK_SNAN_PLUS
const unsigned CCMASK_NONE
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
const unsigned TDCMASK_ZERO_PLUS
const unsigned TDCMASK_QNAN_PLUS
const unsigned TDCMASK_ZERO_MINUS
unsigned even128(bool Is32bit)
const unsigned CCMASK_TM_ALL_1
const unsigned CCMASK_LOGICAL_BORROW
const unsigned ELFNumArgFPRs
const unsigned CCMASK_CMP_UO
const unsigned CCMASK_LOGICAL
const unsigned CCMASK_TM_MSB_1
const unsigned TDCMASK_SNAN_MINUS
initializer< Ty > init(const Ty &Val)
support::ulittle32_t Word
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
@ Define
Register definition.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
testing::Matcher< const detail::ErrorHolder & > Failed()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
LLVM_ABI void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
@ Fast
Assign the register banks as fast as possible (default).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
UndefPoisonKind
Enumeration to track whether we are interested in Undef, Poison, or both.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
AddressingMode(bool LongDispl, bool IdxReg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isVectorOf(EVT EltVT) const
Return true if this is a vector with matching element type.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
SystemZVectorConstantInfo(APInt IntImm)
SmallVector< unsigned, 2 > OpVals
bool isVectorConstantLegal(const SystemZSubtarget &Subtarget)
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setDiscardResult(bool Value=true)
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
CallLoweringInfo & setNoReturn(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
CallLoweringInfo & setCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList, AttributeSet ResultAttrs={})
This structure is used to pass arguments to makeLibCall function.