27#include "llvm/IR/IntrinsicsS390.h"
37#define DEBUG_TYPE "systemz-lower"
43 cl::desc(
"Verify that narrow int args are properly extended per the "
50 : Op0(Op0In), Op1(Op1In), Chain(ChainIn),
51 Opcode(0), ICmpType(0), CCValid(0), CCMask(0) {}
101 if (Subtarget.hasHighWord())
107 if (Subtarget.hasVector()) {
116 if (Subtarget.hasVectorEnhancements1())
121 if (Subtarget.hasVector()) {
131 if (Subtarget.hasVector())
158 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
159 I <= MVT::LAST_FP_VALUETYPE;
185 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
186 I <= MVT::LAST_INTEGER_VALUETYPE;
217 if (Subtarget.hasPopulationCount())
243 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
264 if (!Subtarget.hasVectorEnhancements3()) {
291 if (Subtarget.hasVectorEnhancements3()) {
334 {MVT::i8, MVT::i16, MVT::i32},
Legal);
336 {MVT::i8, MVT::i16},
Legal);
357 if (Subtarget.hasMiscellaneousExtensions4()) {
364 if (Subtarget.hasMiscellaneousExtensions3()) {
457 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
462 if (Subtarget.hasVectorEnhancements3() &&
463 VT != MVT::v16i8 && VT != MVT::v8i16) {
473 if (Subtarget.hasVectorEnhancements1())
507 if (Subtarget.hasVector()) {
529 if (Subtarget.hasVectorEnhancements2()) {
555 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
569 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
570 I <= MVT::LAST_FP_VALUETYPE;
578 if (Subtarget.hasFPExtension()) {
606 if (Subtarget.hasFPExtension()) {
622 if (Subtarget.hasVector()) {
673 if (Subtarget.hasVectorEnhancements1()) {
680 if (Subtarget.hasVectorEnhancements1()) {
736 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
737 MVT::v4f32, MVT::v2f64 }) {
746 if (!Subtarget.hasVectorEnhancements1()) {
752 if (Subtarget.hasVectorEnhancements1())
762 if (Subtarget.hasVectorEnhancements1()) {
774 if (!Subtarget.hasVector()) {
785 if (Subtarget.isTargetzOS()) {
846 return Subtarget.hasSoftFloat();
851 unsigned &NumIntermediates,
MVT &RegisterVT)
const {
854 IntermediateVT = RegisterVT = MVT::v8f16;
855 return NumIntermediates =
859 Context, CC, VT, IntermediateVT, NumIntermediates, RegisterVT);
906 return Subtarget.hasVectorEnhancements1();
919 if (!Subtarget.hasVector() ||
920 (isFP128 && !Subtarget.hasVectorEnhancements1()))
929 uint64_t Byte = IntBits.lshr(
I * 8).trunc(8).getZExtValue();
936 Opcode = SystemZISD::BYTE_MASK;
942 if (SplatBitSize > 64)
949 OpVals.push_back(((
unsigned) SignedValue));
950 Opcode = SystemZISD::REPLICATE;
957 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start, End)) {
961 OpVals.push_back(Start - (64 - SplatBitSize));
962 OpVals.push_back(End - (64 - SplatBitSize));
963 Opcode = SystemZISD::ROTATE_MASK;
975 uint64_t SplatBitsZ = SplatBits.getZExtValue();
976 uint64_t SplatUndefZ = SplatUndef.getZExtValue();
988 return TryValue(SplatBitsZ | Middle);
997 assert(IntBits.getBitWidth() == 128 &&
"Unsupported APInt.");
1003 unsigned HalfSize = Width / 2;
1008 if (HighValue != LowValue || 8 > HalfSize)
1011 SplatBits = HighValue;
1015 SplatBitSize = Width;
1023 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
1027 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
1032 bool ForCodeSize)
const {
1034 if (Imm.isZero() || Imm.isNegZero())
1055 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1057 Register MainDstReg =
MRI.createVirtualRegister(RC);
1058 Register RestoreDstReg =
MRI.createVirtualRegister(RC);
1061 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1114 const int64_t FPOffset = 0;
1123 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
1135 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1136 bool HasFP = Subtarget.getFrameLowering()->hasFP(*MF);
1139 .
addReg(SpecialRegs->getFramePointerRegister())
1147 .
addReg(SpecialRegs->getStackPointerRegister())
1155 Register BCReg =
MRI.createVirtualRegister(PtrRC);
1158 .
addReg(SpecialRegs->getStackPointerRegister())
1159 .
addImm(TFL->getBackchainOffset(*MF))
1170 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1174 MIB.
addRegMask(RegInfo->getNoPreservedMask());
1195 MI.eraseFromParent();
1211 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1214 auto *SpecialRegs = Subtarget.getSpecialRegisters();
1221 const int64_t FPOffset = 0;
1233 SpecialRegs->getFramePointerRegister())
1255 SpecialRegs->getStackPointerRegister())
1264 .
addReg(SpecialRegs->getStackPointerRegister())
1265 .
addImm(TFL->getBackchainOffset(*MF))
1271 MI.eraseFromParent();
1302 if (Subtarget.hasInterlockedAccess1() &&
1335 EVT VT =
Y.getValueType();
1338 if (VT == MVT::i32 || VT == MVT::i64)
1339 return Subtarget.hasMiscellaneousExtensions3();
1342 if (VT.
isVector() || VT == MVT::i128)
1343 return Subtarget.hasVector();
1371 bool MVC = Ty->isIntegerTy(8);
1377static AddressingMode
1380 switch (
II->getIntrinsicID()) {
1382 case Intrinsic::memset:
1383 case Intrinsic::memmove:
1384 case Intrinsic::memcpy:
1391 if (SingleUser->getParent() ==
I->getParent()) {
1394 if (
C->getBitWidth() <= 64 &&
1404 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1418 I->getOperand(0)->getType());
1420 bool IsVectorAccess = MemAccessTy->isVectorTy();
1425 Value *DataOp =
I->getOperand(0);
1427 IsVectorAccess =
true;
1433 User *LoadUser = *
I->user_begin();
1435 IsVectorAccess =
true;
1438 if (IsFPAccess || IsVectorAccess)
1457 Subtarget.hasVector() && (Ty->isVectorTy() || Ty->isIntegerTy(128));
1467 return AM.
Scale == 0;
1474 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1475 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1476 const AttributeList &FuncAttributes,
EVT *LargestVT)
const {
1477 const int MVCFastLen = 16;
1479 if (Limit != ~
unsigned(0)) {
1481 if (
Op.isMemcpy() &&
Op.allowOverlap() &&
Op.size() <= MVCFastLen)
1483 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1485 if (
Op.isZeroMemset())
1490 Context, MemOps, Limit,
Op, DstAS, SrcAS, FuncAttributes, LargestVT);
1495 const AttributeList &FuncAttributes)
const {
1496 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1500 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1502 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1504 return FromBits > ToBits;
1512 return FromBits > ToBits;
1521 if (Constraint.
size() == 1) {
1522 switch (Constraint[0]) {
1548 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1549 switch (Constraint[1]) {
1560 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1570 Value *CallOperandVal = Info.CallOperandVal;
1573 if (!CallOperandVal)
1577 switch (*Constraint) {
1596 if (Subtarget.hasVector())
1627 if (
C->getZExtValue() == 0x7fffffff)
1637static std::pair<unsigned, const TargetRegisterClass *>
1639 const unsigned *Map,
unsigned Size) {
1640 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1641 if (isdigit(Constraint[2])) {
1646 return std::make_pair(Map[Index], RC);
1648 return std::make_pair(0U,
nullptr);
1651std::pair<unsigned, const TargetRegisterClass *>
1654 if (Constraint.
size() == 1) {
1656 switch (Constraint[0]) {
1661 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1663 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1664 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1668 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1669 else if (VT == MVT::i128)
1670 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1671 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1674 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1679 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1681 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1683 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1684 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1689 if (Subtarget.hasVector()) {
1691 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1693 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1695 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1696 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1705 auto getVTSizeInBits = [&VT]() {
1713 if (Constraint[1] ==
'r') {
1714 if (getVTSizeInBits() == 32)
1717 if (getVTSizeInBits() == 128)
1723 if (Constraint[1] ==
'f') {
1725 return std::make_pair(
1727 if (getVTSizeInBits() == 16)
1730 if (getVTSizeInBits() == 32)
1733 if (getVTSizeInBits() == 128)
1739 if (Constraint[1] ==
'v') {
1740 if (!Subtarget.hasVector())
1741 return std::make_pair(
1743 if (getVTSizeInBits() == 16)
1746 if (getVTSizeInBits() == 32)
1749 if (getVTSizeInBits() == 64)
1755 if (Constraint[1] ==
'@') {
1756 if (
StringRef(
"{@cc}").compare(Constraint) == 0)
1757 return std::make_pair(SystemZ::CC, &SystemZ::CCRRegClass);
1770 .
Case(
"r4", Subtarget.isTargetXPLINK64() ? SystemZ::R4D
1771 : SystemZ::NoRegister)
1773 Subtarget.isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1780 const Constant *PersonalityFn)
const {
1781 return Subtarget.isTargetXPLINK64() ? SystemZ::R1D : SystemZ::R6D;
1785 const Constant *PersonalityFn)
const {
1786 return Subtarget.isTargetXPLINK64() ? SystemZ::R2D : SystemZ::R7D;
1801 if (
StringRef(
"{@cc}").compare(OpInfo.ConstraintCode) != 0)
1805 if (OpInfo.ConstraintVT.isVector() || !OpInfo.ConstraintVT.isInteger() ||
1806 OpInfo.ConstraintVT.getSizeInBits() < 8)
1821 if (Constraint.
size() == 1) {
1822 switch (Constraint[0]) {
1827 Op.getValueType()));
1834 Op.getValueType()));
1841 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1848 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1853 if (
C->getZExtValue() == 0x7fffffff)
1855 Op.getValueType()));
1866#include "SystemZGenCallingConv.inc"
1870 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1876 Type *ToType)
const {
1939 if (BitCastToType == MVT::v2i64)
1966 MVT::Untyped,
Hi,
Lo);
1990 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1992 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2003 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
2004 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
2015template <
class ArgTy>
2018 MVT &PartVT,
unsigned &NumParts) {
2019 if (!Args[
I].Flags.isSplit())
2023 PartVT = ArgLocs[
I].getValVT();
2025 for (
unsigned PartIdx =
I + 1;; ++PartIdx) {
2026 assert(PartIdx != ArgLocs.
size() &&
"SplitEnd not found.");
2027 assert(ArgLocs[PartIdx].getValVT() == PartVT &&
"Unsupported split.");
2029 if (Args[PartIdx].Flags.isSplitEnd())
2053 unsigned NumFixedGPRs = 0;
2054 unsigned NumFixedFPRs = 0;
2055 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2068 RC = &SystemZ::GR32BitRegClass;
2072 RC = &SystemZ::GR64BitRegClass;
2076 RC = &SystemZ::FP16BitRegClass;
2080 RC = &SystemZ::FP32BitRegClass;
2084 RC = &SystemZ::FP64BitRegClass;
2088 RC = &SystemZ::FP128BitRegClass;
2097 RC = &SystemZ::VR128BitRegClass;
2111 if (Subtarget.isTargetXPLINK64()) {
2114 ArgSPOffset += XPRegs.getCallFrameSize();
2125 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2129 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2143 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2146 unsigned PartOffset = Ins[
I].PartOffset;
2151 assert(PartOffset &&
"Offset should be non-zero.");
2158 if (IsVarArg && Subtarget.isTargetXPLINK64()) {
2164 Subtarget.getSpecialRegisters());
2170 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2175 if (IsVarArg && Subtarget.isTargetELF()) {
2188 int64_t RegSaveOffset =
2203 &SystemZ::FP64BitRegClass);
2215 if (Subtarget.isTargetXPLINK64()) {
2220 Subtarget.getSpecialRegisters());
2221 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2233 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E; ++
I) {
2240 if (
Reg == SystemZ::R6H ||
Reg == SystemZ::R6L ||
Reg == SystemZ::R6D)
2242 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2249 unsigned Offset,
bool LoadAdr =
false) {
2272 bool LoadAddr =
false;
2294 unsigned ADADelta = 0;
2295 unsigned EPADelta = 8;
2301 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2302 G->getGlobal()->hasPrivateLinkage());
2309 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2355 if (Subtarget.isTargetXPLINK64())
2359 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2363 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2382 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2390 unsigned NumParts = 1;
2394 SlotVT = Outs[
I].VT;
2401 DAG.
getStore(Chain,
DL, ArgValue, SpillSlot, StackPtrInfo));
2404 assert(Outs[
I].PartOffset == 0);
2405 for (
unsigned PartIdx = 1; PartIdx < NumParts; ++PartIdx) {
2408 unsigned PartOffset = Outs[
I].PartOffset;
2414 assert(PartOffset &&
"Offset should be non-zero.");
2416 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2418 ArgValue = SpillSlot;
2435 if (!StackPtr.getNode())
2442 else if (VA.
getLocVT() == MVT::f16)
2455 if (Subtarget.isTargetXPLINK64() && VA.
needsCustom()) {
2459 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2465 if (!MemOpChains.
empty())
2473 if (Subtarget.isTargetXPLINK64()) {
2478 ->getAddressOfCalleeRegister();
2481 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2488 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2491 Callee = DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Callee);
2492 }
else if (IsTailCall) {
2495 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2500 for (
const auto &[Reg,
N] : RegsToPass) {
2507 Ops.push_back(Chain);
2508 Ops.push_back(Callee);
2512 for (
const auto &[Reg,
N] : RegsToPass)
2517 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2518 assert(Mask &&
"Missing call preserved mask for calling convention");
2523 Ops.push_back(Glue);
2532 Chain = DAG.
getNode(SystemZISD::CALL,
DL, NodeTys,
Ops);
2542 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2549 VA.getLocVT(), Glue);
2566 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2568 Args.reserve(
Ops.size());
2574 Entry.IsZExt = !Entry.IsSExt;
2575 Args.push_back(Entry);
2586 .
setCallee(CallConv, RetTy, Callee, std::move(Args))
2597 const Type *RetTy)
const {
2600 for (
auto &Out : Outs)
2601 if (Out.ArgVT.isScalarInteger() && Out.ArgVT.getSizeInBits() > 64)
2605 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Context);
2606 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2618 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2626 if (RetLocs.
empty())
2627 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, Chain);
2636 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2658 return DAG.
getNode(SystemZISD::RET_GLUE,
DL, MVT::Other, RetOps);
2665 unsigned &CCValid) {
2666 unsigned Id =
Op.getConstantOperandVal(1);
2668 case Intrinsic::s390_tbegin:
2669 Opcode = SystemZISD::TBEGIN;
2673 case Intrinsic::s390_tbegin_nofloat:
2674 Opcode = SystemZISD::TBEGIN_NOFLOAT;
2678 case Intrinsic::s390_tend:
2679 Opcode = SystemZISD::TEND;
2692 unsigned Id =
Op.getConstantOperandVal(0);
2694 case Intrinsic::s390_vpkshs:
2695 case Intrinsic::s390_vpksfs:
2696 case Intrinsic::s390_vpksgs:
2697 Opcode = SystemZISD::PACKS_CC;
2701 case Intrinsic::s390_vpklshs:
2702 case Intrinsic::s390_vpklsfs:
2703 case Intrinsic::s390_vpklsgs:
2704 Opcode = SystemZISD::PACKLS_CC;
2708 case Intrinsic::s390_vceqbs:
2709 case Intrinsic::s390_vceqhs:
2710 case Intrinsic::s390_vceqfs:
2711 case Intrinsic::s390_vceqgs:
2712 case Intrinsic::s390_vceqqs:
2713 Opcode = SystemZISD::VICMPES;
2717 case Intrinsic::s390_vchbs:
2718 case Intrinsic::s390_vchhs:
2719 case Intrinsic::s390_vchfs:
2720 case Intrinsic::s390_vchgs:
2721 case Intrinsic::s390_vchqs:
2722 Opcode = SystemZISD::VICMPHS;
2726 case Intrinsic::s390_vchlbs:
2727 case Intrinsic::s390_vchlhs:
2728 case Intrinsic::s390_vchlfs:
2729 case Intrinsic::s390_vchlgs:
2730 case Intrinsic::s390_vchlqs:
2731 Opcode = SystemZISD::VICMPHLS;
2735 case Intrinsic::s390_vtm:
2736 Opcode = SystemZISD::VTM;
2740 case Intrinsic::s390_vfaebs:
2741 case Intrinsic::s390_vfaehs:
2742 case Intrinsic::s390_vfaefs:
2743 Opcode = SystemZISD::VFAE_CC;
2747 case Intrinsic::s390_vfaezbs:
2748 case Intrinsic::s390_vfaezhs:
2749 case Intrinsic::s390_vfaezfs:
2750 Opcode = SystemZISD::VFAEZ_CC;
2754 case Intrinsic::s390_vfeebs:
2755 case Intrinsic::s390_vfeehs:
2756 case Intrinsic::s390_vfeefs:
2757 Opcode = SystemZISD::VFEE_CC;
2761 case Intrinsic::s390_vfeezbs:
2762 case Intrinsic::s390_vfeezhs:
2763 case Intrinsic::s390_vfeezfs:
2764 Opcode = SystemZISD::VFEEZ_CC;
2768 case Intrinsic::s390_vfenebs:
2769 case Intrinsic::s390_vfenehs:
2770 case Intrinsic::s390_vfenefs:
2771 Opcode = SystemZISD::VFENE_CC;
2775 case Intrinsic::s390_vfenezbs:
2776 case Intrinsic::s390_vfenezhs:
2777 case Intrinsic::s390_vfenezfs:
2778 Opcode = SystemZISD::VFENEZ_CC;
2782 case Intrinsic::s390_vistrbs:
2783 case Intrinsic::s390_vistrhs:
2784 case Intrinsic::s390_vistrfs:
2785 Opcode = SystemZISD::VISTR_CC;
2789 case Intrinsic::s390_vstrcbs:
2790 case Intrinsic::s390_vstrchs:
2791 case Intrinsic::s390_vstrcfs:
2792 Opcode = SystemZISD::VSTRC_CC;
2796 case Intrinsic::s390_vstrczbs:
2797 case Intrinsic::s390_vstrczhs:
2798 case Intrinsic::s390_vstrczfs:
2799 Opcode = SystemZISD::VSTRCZ_CC;
2803 case Intrinsic::s390_vstrsb:
2804 case Intrinsic::s390_vstrsh:
2805 case Intrinsic::s390_vstrsf:
2806 Opcode = SystemZISD::VSTRS_CC;
2810 case Intrinsic::s390_vstrszb:
2811 case Intrinsic::s390_vstrszh:
2812 case Intrinsic::s390_vstrszf:
2813 Opcode = SystemZISD::VSTRSZ_CC;
2817 case Intrinsic::s390_vfcedbs:
2818 case Intrinsic::s390_vfcesbs:
2819 Opcode = SystemZISD::VFCMPES;
2823 case Intrinsic::s390_vfchdbs:
2824 case Intrinsic::s390_vfchsbs:
2825 Opcode = SystemZISD::VFCMPHS;
2829 case Intrinsic::s390_vfchedbs:
2830 case Intrinsic::s390_vfchesbs:
2831 Opcode = SystemZISD::VFCMPHES;
2835 case Intrinsic::s390_vftcidb:
2836 case Intrinsic::s390_vftcisb:
2837 Opcode = SystemZISD::VFTCI;
2841 case Intrinsic::s390_tdc:
2842 Opcode = SystemZISD::TDC;
2855 unsigned NumOps =
Op.getNumOperands();
2858 Ops.push_back(
Op.getOperand(0));
2860 Ops.push_back(
Op.getOperand(
I));
2862 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2876 unsigned NumOps =
Op.getNumOperands();
2882 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2883 "Unhandled intrinsic with f16 operand.");
2886 Ops.push_back(CurrOper);
2900 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2901 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2902 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2928 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2931 int64_t
Value = ConstOp1->getSExtValue();
2947 if (!
C.Op0.hasOneUse() ||
2954 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2955 if ((NumBits != 8 && NumBits != 16) ||
2956 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2962 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2965 uint64_t Mask = (1 << NumBits) - 1;
2968 int64_t SignedValue = ConstOp1->getSExtValue();
2975 }
else if (NumBits == 8) {
3001 if (
C.Op0.getValueType() != MVT::i32 ||
3002 Load->getExtensionType() != ExtType) {
3004 Load->getBasePtr(), Load->getPointerInfo(),
3005 Load->getMemoryVT(), Load->getAlign(),
3006 Load->getMemOperand()->getFlags());
3012 if (
C.Op1.getValueType() != MVT::i32 ||
3013 Value != ConstOp1->getZExtValue())
3023 if (Load->getMemoryVT() == MVT::i8)
3026 switch (Load->getExtensionType()) {
3043 if (
C.Op0.getValueType() == MVT::i128)
3045 if (
C.Op0.getValueType() == MVT::f128)
3057 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
3086 unsigned Opcode0 =
C.Op0.getOpcode();
3093 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3108 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3109 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3131 if (C1 && C1->isZero()) {
3150 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3153 if (C1 && C1->getZExtValue() == 32) {
3154 SDValue ShlOp0 =
C.Op0.getOperand(0);
3173 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3176 C.Op1->getAsZExtVal() == 0) {
3178 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3179 C.Op0.getValueSizeInBits().getFixedValue()) {
3180 unsigned Type = L->getExtensionType();
3183 C.Op0 =
C.Op0.getOperand(0);
3197 uint64_t Amount = Shift->getZExtValue();
3198 if (Amount >=
N.getValueSizeInBits())
3213 unsigned ICmpType) {
3214 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3236 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3242 if (EffectivelyUnsigned && CmpVal <
Low) {
3250 if (CmpVal == Mask) {
3256 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3262 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3270 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3276 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3305 if (
C.Op0.getValueType() == MVT::i128) {
3311 if (Mask && Mask->getAPIntValue() == 0) {
3312 C.Opcode = SystemZISD::VTM;
3329 uint64_t CmpVal = ConstOp1->getZExtValue();
3336 NewC.Op0 =
C.Op0.getOperand(0);
3337 NewC.Op1 =
C.Op0.getOperand(1);
3341 MaskVal = Mask->getZExtValue();
3361 MaskVal = -(CmpVal & -CmpVal);
3370 unsigned NewCCMask, ShiftVal;
3374 (MaskVal >> ShiftVal != 0) &&
3375 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3377 MaskVal >> ShiftVal,
3381 MaskVal >>= ShiftVal;
3385 (MaskVal << ShiftVal != 0) &&
3386 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3388 MaskVal << ShiftVal,
3392 MaskVal <<= ShiftVal;
3401 C.Opcode = SystemZISD::TM;
3403 if (Mask && Mask->getZExtValue() == MaskVal)
3408 C.CCMask = NewCCMask;
3414 if (
C.Opcode != SystemZISD::ICMP)
3416 if (
C.Op0.getValueType() != MVT::i128)
3427 Src = Src.getOperand(0);
3430 unsigned Opcode = 0;
3431 if (Src.hasOneUse()) {
3432 switch (Src.getOpcode()) {
3433 case SystemZISD::VICMPE: Opcode = SystemZISD::VICMPES;
break;
3434 case SystemZISD::VICMPH: Opcode = SystemZISD::VICMPHS;
break;
3435 case SystemZISD::VICMPHL: Opcode = SystemZISD::VICMPHLS;
break;
3436 case SystemZISD::VFCMPE: Opcode = SystemZISD::VFCMPES;
break;
3437 case SystemZISD::VFCMPH: Opcode = SystemZISD::VFCMPHS;
break;
3438 case SystemZISD::VFCMPHE: Opcode = SystemZISD::VFCMPHES;
break;
3444 C.Op0 = Src->getOperand(0);
3445 C.Op1 = Src->getOperand(1);
3449 C.CCMask ^=
C.CCValid;
3461 C.Opcode = SystemZISD::VICMPES;
3473 bool Swap =
false, Invert =
false;
3485 C.Opcode = SystemZISD::UCMP128HI;
3487 C.Opcode = SystemZISD::SCMP128HI;
3492 C.CCMask ^=
C.CCValid;
3503 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3506 if ((~Known.
Zero).getZExtValue() & ~Mask->getZExtValue())
3509 C.Op0 =
C.Op0.getOperand(0);
3521 C.CCValid = CCValid;
3524 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3527 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3531 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3534 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3538 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3541 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3544 C.CCMask &= CCValid;
3552 bool IsSignaling =
false) {
3555 unsigned Opcode, CCValid;
3567 Comparison
C(CmpOp0, CmpOp1, Chain);
3569 if (
C.Op0.getValueType().isFloatingPoint()) {
3572 C.Opcode = SystemZISD::FCMP;
3573 else if (!IsSignaling)
3574 C.Opcode = SystemZISD::STRICT_FCMP;
3576 C.Opcode = SystemZISD::STRICT_FCMPS;
3581 C.Opcode = SystemZISD::ICMP;
3616 if (!
C.Op1.getNode()) {
3618 switch (
C.Op0.getOpcode()) {
3629 if (
C.Opcode == SystemZISD::ICMP)
3630 return DAG.
getNode(SystemZISD::ICMP,
DL, MVT::i32,
C.Op0,
C.Op1,
3632 if (
C.Opcode == SystemZISD::TM) {
3635 return DAG.
getNode(SystemZISD::TM,
DL, MVT::i32,
C.Op0,
C.Op1,
3638 if (
C.Opcode == SystemZISD::VICMPES ||
3639 C.Opcode == SystemZISD::VICMPHS ||
3640 C.Opcode == SystemZISD::VICMPHLS ||
3641 C.Opcode == SystemZISD::VFCMPES ||
3642 C.Opcode == SystemZISD::VFCMPHS ||
3643 C.Opcode == SystemZISD::VFCMPHES) {
3644 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3651 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3653 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3662 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3663 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3688 unsigned CCValid,
unsigned CCMask) {
3693 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL, MVT::i32,
Ops);
3771 int Mask[] = { Start, -1, Start + 1, -1 };
3775 return DAG.
getNode(SystemZISD::STRICT_VEXTEND,
DL, VTs, Chain,
Op);
3777 return DAG.
getNode(SystemZISD::VEXTEND,
DL, MVT::v2f64,
Op);
3791 !Subtarget.hasVectorEnhancements1()) {
3797 SDVTList VTs = DAG.
getVTList(MVT::v2i64, MVT::Other);
3810 return DAG.
getNode(SystemZISD::PACK,
DL, VT, HRes, LRes);
3813 SDVTList VTs = DAG.
getVTList(VT, MVT::Other);
3814 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3816 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3829 bool IsSignaling)
const {
3832 assert (!IsSignaling || Chain);
3835 bool Invert =
false;
3843 assert(IsFP &&
"Unexpected integer comparison");
3845 DL, VT, CmpOp1, CmpOp0, Chain);
3847 DL, VT, CmpOp0, CmpOp1, Chain);
3851 LT.getValue(1),
GE.getValue(1));
3860 assert(IsFP &&
"Unexpected integer comparison");
3862 DL, VT, CmpOp1, CmpOp0, Chain);
3864 DL, VT, CmpOp0, CmpOp1, Chain);
3868 LT.getValue(1),
GT.getValue(1));
3889 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3893 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3898 Chain =
Cmp.getValue(1);
3906 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3919 EVT VT =
Op.getValueType();
3921 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3930 bool IsSignaling)
const {
3936 EVT VT =
Op.getNode()->getValueType(0);
3938 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3939 Chain, IsSignaling);
3961 SystemZISD::BR_CCMASK,
DL,
Op.getValueType(),
Op.getOperand(0),
3995 C.CCMask ^=
C.CCValid;
4003 Op = SystemZISD::VICMPE;
4007 Op = SystemZISD::VICMPHL;
4009 Op = SystemZISD::VICMPH;
4048 C.Op1->getAsZExtVal() == 0) {
4055 if (Subtarget.hasVectorEnhancements3() &&
4056 C.Opcode == SystemZISD::ICMP &&
4057 C.Op0.getValueType() == MVT::i128 &&
4067 return DAG.
getNode(SystemZISD::SELECT_CCMASK,
DL,
Op.getValueType(),
Ops);
4073 const GlobalValue *GV =
Node->getGlobal();
4079 if (Subtarget.isPC32DBLSymbol(GV, CM)) {
4082 uint64_t Anchor =
Offset & ~uint64_t(0xfff);
4101 }
else if (Subtarget.isTargetELF()) {
4106 }
else if (Subtarget.isTargetzOS()) {
4137 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4142 Ops.push_back(Chain);
4144 Node->getValueType(0),
4153 const TargetRegisterInfo *
TRI = Subtarget.getRegisterInfo();
4154 const uint32_t *
Mask =
4156 assert(Mask &&
"Missing call preserved mask for calling convention");
4160 Ops.push_back(Glue);
4163 SDVTList NodeTys = DAG.
getVTList(MVT::Other, MVT::Glue);
4171SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4195 const GlobalValue *GV =
Node->getGlobal();
4203 SDValue TP = lowerThreadPointer(
DL, DAG);
4210 SystemZConstantPoolValue *CPV =
4219 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_GDCALL,
Offset);
4225 SystemZConstantPoolValue *CPV =
4234 Offset = lowerTLSGetOffset(Node, DAG, SystemZISD::TLS_LDCALL,
Offset);
4239 SystemZMachineFunctionInfo* MFI =
4268 SystemZConstantPoolValue *CPV =
4302 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4319 return DAG.
getNode(SystemZISD::PCREL_WRAPPER,
DL, PtrVT, Result);
4324 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4326 MachineFrameInfo &MFI = MF.getFrameInfo();
4330 unsigned Depth =
Op.getConstantOperandVal(0);
4337 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4342 if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
4348 MachinePointerInfo());
4363 unsigned Depth =
Op.getConstantOperandVal(0);
4368 if (!MF.
getSubtarget<SystemZSubtarget>().hasBackChain())
4371 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4372 const auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
4373 int Offset = TFL->getReturnAddressOffset(MF);
4377 MachinePointerInfo());
4382 SystemZCallingConventionRegisters *CCR = Subtarget.getSpecialRegisters();
4384 &SystemZ::GR64BitRegClass);
4392 EVT InVT =
In.getValueType();
4393 EVT ResVT =
Op.getValueType();
4401 LoadN->getBasePtr(), LoadN->getMemOperand());
4407 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4409 if (Subtarget.hasHighWord()) {
4413 MVT::i64,
SDValue(U64, 0), In);
4421 DL, MVT::f32, Out64);
4423 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4426 MVT::f64,
SDValue(U64, 0), In);
4428 if (Subtarget.hasHighWord())
4441 if (Subtarget.isTargetXPLINK64())
4442 return lowerVASTART_XPLINK(
Op, DAG);
4444 return lowerVASTART_ELF(
Op, DAG);
4450 SystemZMachineFunctionInfo *FuncInfo =
4451 MF.
getInfo<SystemZMachineFunctionInfo>();
4461 MachinePointerInfo(SV));
4467 SystemZMachineFunctionInfo *FuncInfo =
4468 MF.
getInfo<SystemZMachineFunctionInfo>();
4477 const unsigned NumFields = 4;
4488 for (
unsigned I = 0;
I < NumFields; ++
I) {
4493 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4494 MachinePointerInfo(SV,
Offset));
4512 Align(8),
false,
false,
4513 nullptr, std::nullopt, MachinePointerInfo(DstSV),
4514 MachinePointerInfo(SrcSV));
4518SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4520 if (Subtarget.isTargetXPLINK64())
4521 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4523 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4527SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4529 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4539 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4542 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4543 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4549 if (ExtraAlignSpace)
4553 bool IsSigned =
false;
4554 bool DoesNotReturn =
false;
4555 bool IsReturnValueUsed =
false;
4556 EVT VT =
Op.getValueType();
4566 auto &Regs = Subtarget.getSpecialRegisters<SystemZXPLINK64Registers>();
4578 if (ExtraAlignSpace) {
4590SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4592 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
4595 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
4604 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4607 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4608 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4619 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4620 MachinePointerInfo());
4623 if (ExtraAlignSpace)
4630 NewSP = DAG.
getNode(SystemZISD::PROBED_ALLOCA,
DL,
4631 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4647 if (RequiredAlign > StackAlign) {
4657 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4658 MachinePointerInfo());
4664SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4668 return DAG.
getNode(SystemZISD::ADJDYNALLOC,
DL, MVT::i64);
4673 unsigned Opcode)
const {
4674 EVT VT =
Op.getValueType();
4680 assert(Subtarget.hasMiscellaneousExtensions2());
4685 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4691 EVT VT =
Op.getValueType();
4699 else if (Subtarget.hasMiscellaneousExtensions2())
4704 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4739 EVT VT =
Op.getValueType();
4752 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4760 EVT VT =
Op.getValueType();
4780 EVT VT =
Op.getValueType();
4787 Op.getOperand(0),
Op.getOperand(1),
Ops[1],
Ops[0]);
4792 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4804 if ((Masks[0] >> 32) == 0xffffffff && uint32_t(Masks[1]) == 0xffffffff)
4806 else if ((Masks[1] >> 32) == 0xffffffff && uint32_t(Masks[0]) == 0xffffffff)
4843 MVT::i64, HighOp, Low32);
4849 SDNode *
N =
Op.getNode();
4854 if (
N->getValueType(0) == MVT::i128) {
4855 unsigned BaseOp = 0;
4856 unsigned FlagOp = 0;
4857 bool IsBorrow =
false;
4858 switch (
Op.getOpcode()) {
4862 FlagOp = SystemZISD::VACC;
4866 FlagOp = SystemZISD::VSCBI;
4881 unsigned BaseOp = 0;
4882 unsigned CCValid = 0;
4883 unsigned CCMask = 0;
4885 switch (
Op.getOpcode()) {
4888 BaseOp = SystemZISD::SADDO;
4893 BaseOp = SystemZISD::SSUBO;
4898 BaseOp = SystemZISD::UADDO;
4903 BaseOp = SystemZISD::USUBO;
4909 SDVTList VTs = DAG.
getVTList(
N->getValueType(0), MVT::i32);
4913 if (
N->getValueType(1) == MVT::i1)
4939 SDNode *
N =
Op.getNode();
4940 MVT VT =
N->getSimpleValueType(0);
4951 if (VT == MVT::i128) {
4952 unsigned BaseOp = 0;
4953 unsigned FlagOp = 0;
4954 bool IsBorrow =
false;
4955 switch (
Op.getOpcode()) {
4958 BaseOp = SystemZISD::VAC;
4959 FlagOp = SystemZISD::VACCC;
4962 BaseOp = SystemZISD::VSBI;
4963 FlagOp = SystemZISD::VSBCBI;
4982 unsigned BaseOp = 0;
4983 unsigned CCValid = 0;
4984 unsigned CCMask = 0;
4986 switch (
Op.getOpcode()) {
4992 BaseOp = SystemZISD::ADDCARRY;
5000 BaseOp = SystemZISD::SUBCARRY;
5011 SDVTList VTs = DAG.
getVTList(VT, MVT::i32);
5015 if (
N->getValueType(1) == MVT::i1)
5023 EVT VT =
Op.getValueType();
5025 Op =
Op.getOperand(0);
5048 Op = DAG.
getNode(SystemZISD::VSRL_BY_SCALAR,
DL, VT,
Op, Shift);
5060 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Tmp);
5073 if (NumSignificantBits == 0)
5079 BitSize = std::min(BitSize, OrigBitSize);
5088 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
5090 if (BitSize != OrigBitSize)
5127 EVT RegVT =
Op.getValueType();
5129 return lowerATOMIC_LDST_I128(
Op, DAG);
5130 return lowerLoadF16(
Op, DAG);
5136 if (
Node->getMemoryVT().getSizeInBits() == 128)
5137 return lowerATOMIC_LDST_I128(
Op, DAG);
5138 return lowerStoreF16(
Op, DAG);
5145 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5146 "Only custom lowering i128 or f128.");
5159 EVT WideVT = MVT::i32;
5182 unsigned Opcode)
const {
5186 EVT NarrowVT =
Node->getMemoryVT();
5187 EVT WideVT = MVT::i32;
5188 if (NarrowVT == WideVT)
5195 MachineMemOperand *MMO =
Node->getMemOperand();
5199 if (Opcode == SystemZISD::ATOMIC_LOADW_SUB)
5201 Opcode = SystemZISD::ATOMIC_LOADW_ADD;
5206 SDValue AlignedAddr, BitShift, NegBitShift;
5214 if (Opcode != SystemZISD::ATOMIC_SWAPW)
5217 if (Opcode == SystemZISD::ATOMIC_LOADW_AND ||
5218 Opcode == SystemZISD::ATOMIC_LOADW_NAND)
5223 SDVTList VTList = DAG.
getVTList(WideVT, MVT::Other);
5224 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5244 EVT MemVT =
Node->getMemoryVT();
5245 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5247 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5248 assert(Subtarget.hasInterlockedAccess1() &&
5249 "Should have been expanded by AtomicExpand pass.");
5255 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5256 Node->getMemOperand());
5259 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_SUB);
5270 MachineMemOperand *MMO =
Node->getMemOperand();
5273 if (
Node->getMemoryVT() == MVT::i128) {
5282 EVT NarrowVT =
Node->getMemoryVT();
5283 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5284 if (NarrowVT == WideVT) {
5285 SDVTList Tys = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5286 SDValue Ops[] = { ChainIn, Addr, CmpVal, SwapVal };
5288 DL, Tys,
Ops, NarrowVT, MMO);
5302 SDValue AlignedAddr, BitShift, NegBitShift;
5306 SDVTList VTList = DAG.
getVTList(WideVT, MVT::i32, MVT::Other);
5307 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5310 VTList,
Ops, NarrowVT, MMO);
5324SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5347 auto *Regs = Subtarget.getSpecialRegisters();
5350 "in GHC calling convention");
5352 Regs->getStackPointerRegister(),
Op.getValueType());
5358 auto *Regs = Subtarget.getSpecialRegisters();
5359 bool StoreBackchain = MF.
getSubtarget<SystemZSubtarget>().hasBackChain();
5363 "in GHC calling convention");
5370 if (StoreBackchain) {
5372 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5373 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5374 MachinePointerInfo());
5377 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5380 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5381 MachinePointerInfo());
5388 bool IsData =
Op.getConstantOperandVal(4);
5391 return Op.getOperand(0);
5394 bool IsWrite =
Op.getConstantOperandVal(2);
5401 Node->getMemoryVT(),
Node->getMemOperand());
5405SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5407 unsigned Opcode, CCValid;
5409 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5420SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5422 unsigned Opcode, CCValid;
5425 if (
Op->getNumValues() == 1)
5427 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5432 unsigned Id =
Op.getConstantOperandVal(0);
5434 case Intrinsic::thread_pointer:
5435 return lowerThreadPointer(SDLoc(
Op), DAG);
5437 case Intrinsic::s390_vpdi:
5438 return DAG.
getNode(SystemZISD::PERMUTE_DWORDS, SDLoc(
Op),
Op.getValueType(),
5439 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5441 case Intrinsic::s390_vperm:
5442 return DAG.
getNode(SystemZISD::PERMUTE, SDLoc(
Op),
Op.getValueType(),
5443 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5445 case Intrinsic::s390_vuphb:
5446 case Intrinsic::s390_vuphh:
5447 case Intrinsic::s390_vuphf:
5448 case Intrinsic::s390_vuphg:
5449 return DAG.
getNode(SystemZISD::UNPACK_HIGH, SDLoc(
Op),
Op.getValueType(),
5452 case Intrinsic::s390_vuplhb:
5453 case Intrinsic::s390_vuplhh:
5454 case Intrinsic::s390_vuplhf:
5455 case Intrinsic::s390_vuplhg:
5456 return DAG.
getNode(SystemZISD::UNPACKL_HIGH, SDLoc(
Op),
Op.getValueType(),
5459 case Intrinsic::s390_vuplb:
5460 case Intrinsic::s390_vuplhw:
5461 case Intrinsic::s390_vuplf:
5462 case Intrinsic::s390_vuplg:
5463 return DAG.
getNode(SystemZISD::UNPACK_LOW, SDLoc(
Op),
Op.getValueType(),
5466 case Intrinsic::s390_vupllb:
5467 case Intrinsic::s390_vupllh:
5468 case Intrinsic::s390_vupllf:
5469 case Intrinsic::s390_vupllg:
5470 return DAG.
getNode(SystemZISD::UNPACKL_LOW, SDLoc(
Op),
Op.getValueType(),
5473 case Intrinsic::s390_vsumb:
5474 case Intrinsic::s390_vsumh:
5475 case Intrinsic::s390_vsumgh:
5476 case Intrinsic::s390_vsumgf:
5477 case Intrinsic::s390_vsumqf:
5478 case Intrinsic::s390_vsumqg:
5479 return DAG.
getNode(SystemZISD::VSUM, SDLoc(
Op),
Op.getValueType(),
5480 Op.getOperand(1),
Op.getOperand(2));
5482 case Intrinsic::s390_vaq:
5484 Op.getOperand(1),
Op.getOperand(2));
5485 case Intrinsic::s390_vaccb:
5486 case Intrinsic::s390_vacch:
5487 case Intrinsic::s390_vaccf:
5488 case Intrinsic::s390_vaccg:
5489 case Intrinsic::s390_vaccq:
5490 return DAG.
getNode(SystemZISD::VACC, SDLoc(
Op),
Op.getValueType(),
5491 Op.getOperand(1),
Op.getOperand(2));
5492 case Intrinsic::s390_vacq:
5493 return DAG.
getNode(SystemZISD::VAC, SDLoc(
Op),
Op.getValueType(),
5494 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5495 case Intrinsic::s390_vacccq:
5496 return DAG.
getNode(SystemZISD::VACCC, SDLoc(
Op),
Op.getValueType(),
5497 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5499 case Intrinsic::s390_vsq:
5501 Op.getOperand(1),
Op.getOperand(2));
5502 case Intrinsic::s390_vscbib:
5503 case Intrinsic::s390_vscbih:
5504 case Intrinsic::s390_vscbif:
5505 case Intrinsic::s390_vscbig:
5506 case Intrinsic::s390_vscbiq:
5507 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(
Op),
Op.getValueType(),
5508 Op.getOperand(1),
Op.getOperand(2));
5509 case Intrinsic::s390_vsbiq:
5510 return DAG.
getNode(SystemZISD::VSBI, SDLoc(
Op),
Op.getValueType(),
5511 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5512 case Intrinsic::s390_vsbcbiq:
5513 return DAG.
getNode(SystemZISD::VSBCBI, SDLoc(
Op),
Op.getValueType(),
5514 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5516 case Intrinsic::s390_vmhb:
5517 case Intrinsic::s390_vmhh:
5518 case Intrinsic::s390_vmhf:
5519 case Intrinsic::s390_vmhg:
5520 case Intrinsic::s390_vmhq:
5522 Op.getOperand(1),
Op.getOperand(2));
5523 case Intrinsic::s390_vmlhb:
5524 case Intrinsic::s390_vmlhh:
5525 case Intrinsic::s390_vmlhf:
5526 case Intrinsic::s390_vmlhg:
5527 case Intrinsic::s390_vmlhq:
5529 Op.getOperand(1),
Op.getOperand(2));
5531 case Intrinsic::s390_vmahb:
5532 case Intrinsic::s390_vmahh:
5533 case Intrinsic::s390_vmahf:
5534 case Intrinsic::s390_vmahg:
5535 case Intrinsic::s390_vmahq:
5536 return DAG.
getNode(SystemZISD::VMAH, SDLoc(
Op),
Op.getValueType(),
5537 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5538 case Intrinsic::s390_vmalhb:
5539 case Intrinsic::s390_vmalhh:
5540 case Intrinsic::s390_vmalhf:
5541 case Intrinsic::s390_vmalhg:
5542 case Intrinsic::s390_vmalhq:
5543 return DAG.
getNode(SystemZISD::VMALH, SDLoc(
Op),
Op.getValueType(),
5544 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5546 case Intrinsic::s390_vmeb:
5547 case Intrinsic::s390_vmeh:
5548 case Intrinsic::s390_vmef:
5549 case Intrinsic::s390_vmeg:
5550 return DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5551 Op.getOperand(1),
Op.getOperand(2));
5552 case Intrinsic::s390_vmleb:
5553 case Intrinsic::s390_vmleh:
5554 case Intrinsic::s390_vmlef:
5555 case Intrinsic::s390_vmleg:
5556 return DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5557 Op.getOperand(1),
Op.getOperand(2));
5558 case Intrinsic::s390_vmob:
5559 case Intrinsic::s390_vmoh:
5560 case Intrinsic::s390_vmof:
5561 case Intrinsic::s390_vmog:
5562 return DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5563 Op.getOperand(1),
Op.getOperand(2));
5564 case Intrinsic::s390_vmlob:
5565 case Intrinsic::s390_vmloh:
5566 case Intrinsic::s390_vmlof:
5567 case Intrinsic::s390_vmlog:
5568 return DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5569 Op.getOperand(1),
Op.getOperand(2));
5571 case Intrinsic::s390_vmaeb:
5572 case Intrinsic::s390_vmaeh:
5573 case Intrinsic::s390_vmaef:
5574 case Intrinsic::s390_vmaeg:
5576 DAG.
getNode(SystemZISD::VME, SDLoc(
Op),
Op.getValueType(),
5577 Op.getOperand(1),
Op.getOperand(2)),
5579 case Intrinsic::s390_vmaleb:
5580 case Intrinsic::s390_vmaleh:
5581 case Intrinsic::s390_vmalef:
5582 case Intrinsic::s390_vmaleg:
5584 DAG.
getNode(SystemZISD::VMLE, SDLoc(
Op),
Op.getValueType(),
5585 Op.getOperand(1),
Op.getOperand(2)),
5587 case Intrinsic::s390_vmaob:
5588 case Intrinsic::s390_vmaoh:
5589 case Intrinsic::s390_vmaof:
5590 case Intrinsic::s390_vmaog:
5592 DAG.
getNode(SystemZISD::VMO, SDLoc(
Op),
Op.getValueType(),
5593 Op.getOperand(1),
Op.getOperand(2)),
5595 case Intrinsic::s390_vmalob:
5596 case Intrinsic::s390_vmaloh:
5597 case Intrinsic::s390_vmalof:
5598 case Intrinsic::s390_vmalog:
5600 DAG.
getNode(SystemZISD::VMLO, SDLoc(
Op),
Op.getValueType(),
5601 Op.getOperand(1),
Op.getOperand(2)),
5622 { SystemZISD::MERGE_HIGH, 8,
5623 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5625 { SystemZISD::MERGE_HIGH, 4,
5626 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5628 { SystemZISD::MERGE_HIGH, 2,
5629 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5631 { SystemZISD::MERGE_HIGH, 1,
5632 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5634 { SystemZISD::MERGE_LOW, 8,
5635 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5637 { SystemZISD::MERGE_LOW, 4,
5638 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5640 { SystemZISD::MERGE_LOW, 2,
5641 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5643 { SystemZISD::MERGE_LOW, 1,
5644 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5646 { SystemZISD::PACK, 4,
5647 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5649 { SystemZISD::PACK, 2,
5650 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5652 { SystemZISD::PACK, 1,
5653 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5655 { SystemZISD::PERMUTE_DWORDS, 4,
5656 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5658 { SystemZISD::PERMUTE_DWORDS, 1,
5659 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5673 OpNo0 = OpNo1 = OpNos[1];
5674 }
else if (OpNos[1] < 0) {
5675 OpNo0 = OpNo1 = OpNos[0];
5693 unsigned &OpNo0,
unsigned &OpNo1) {
5694 int OpNos[] = { -1, -1 };
5707 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5709 OpNos[ModelOpNo] = RealOpNo;
5717 unsigned &OpNo0,
unsigned &OpNo1) {
5734 int Elt = Bytes[From];
5737 Transform[From] = -1;
5739 while (
P.Bytes[To] != Elt) {
5744 Transform[From] = To;
5768 Bytes.
resize(NumElements * BytesPerElement, -1);
5769 for (
unsigned I = 0;
I < NumElements; ++
I) {
5770 int Index = VSN->getMaskElt(
I);
5772 for (
unsigned J = 0; J < BytesPerElement; ++J)
5773 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5777 if (SystemZISD::SPLAT == ShuffleOp.
getOpcode() &&
5780 Bytes.
resize(NumElements * BytesPerElement, -1);
5781 for (
unsigned I = 0;
I < NumElements; ++
I)
5782 for (
unsigned J = 0; J < BytesPerElement; ++J)
5783 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5794 unsigned BytesPerElement,
int &
Base) {
5796 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5797 if (Bytes[Start +
I] >= 0) {
5798 unsigned Elem = Bytes[Start +
I];
5802 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5804 }
else if (
unsigned(
Base) != Elem -
I)
5817 unsigned &StartIndex,
unsigned &OpNo0,
5819 int OpNos[] = { -1, -1 };
5821 for (
unsigned I = 0;
I < 16; ++
I) {
5822 int Index = Bytes[
I];
5828 Shift = ExpectedShift;
5829 else if (Shift != ExpectedShift)
5833 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5835 OpNos[ModelOpNo] = RealOpNo;
5848 unsigned InBytes = (
P.Opcode == SystemZISD::PERMUTE_DWORDS ? 8 :
5849 P.Opcode == SystemZISD::PACK ?
P.Operand * 2 :
5857 if (
P.Opcode == SystemZISD::PERMUTE_DWORDS) {
5859 Op = DAG.
getNode(SystemZISD::PERMUTE_DWORDS,
DL, InVT, Op0, Op1, Op2);
5860 }
else if (
P.Opcode == SystemZISD::PACK) {
5863 Op = DAG.
getNode(SystemZISD::PACK,
DL, OutVT, Op0, Op1);
5872 N =
N->getOperand(0);
5875 return Op->getZExtValue() == 0;
5881 for (
unsigned I = 0;
I < Num ;
I++)
5893 for (
unsigned I = 0;
I < 2; ++
I)
5897 unsigned StartIndex, OpNo0, OpNo1;
5899 return DAG.
getNode(SystemZISD::SHL_DOUBLE,
DL, MVT::v16i8,
Ops[OpNo0],
5906 if (ZeroVecIdx != UINT32_MAX) {
5907 bool MaskFirst =
true;
5912 if (OpNo == ZeroVecIdx &&
I == 0) {
5917 if (OpNo != ZeroVecIdx && Byte == 0) {
5924 if (ZeroIdx != -1) {
5927 if (Bytes[
I] >= 0) {
5930 if (OpNo == ZeroVecIdx)
5942 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Mask, Src,
5945 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8, Src, Mask,
5957 return DAG.
getNode(SystemZISD::PERMUTE,
DL, MVT::v16i8,
Ops[0],
5963struct GeneralShuffle {
5964 GeneralShuffle(EVT vt)
5965 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
5969 void tryPrepareForUnpack();
5970 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
5985 unsigned UnpackFromEltSize;
5992void GeneralShuffle::addUndef() {
5994 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5995 Bytes.push_back(-1);
6004bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
6010 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
6015 if (FromBytesPerElement < BytesPerElement)
6019 (FromBytesPerElement - BytesPerElement));
6022 while (
Op.getNode()) {
6024 Op =
Op.getOperand(0);
6040 }
else if (
Op.isUndef()) {
6049 for (; OpNo <
Ops.size(); ++OpNo)
6050 if (
Ops[OpNo] ==
Op)
6052 if (OpNo ==
Ops.size())
6057 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
6058 Bytes.push_back(
Base +
I);
6067 if (
Ops.size() == 0)
6071 tryPrepareForUnpack();
6074 if (
Ops.size() == 1)
6086 unsigned Stride = 1;
6087 for (; Stride * 2 <
Ops.size(); Stride *= 2) {
6088 for (
unsigned I = 0;
I <
Ops.size() - Stride;
I += Stride * 2) {
6098 else if (OpNo ==
I + Stride)
6109 if (NewBytes[J] >= 0) {
6111 "Invalid double permute");
6114 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6120 if (NewBytes[J] >= 0)
6136 unsigned OpNo0, OpNo1;
6140 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6145 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6152 dbgs() << Msg.c_str() <<
" { ";
6153 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6154 dbgs() << Bytes[
I] <<
" ";
6162void GeneralShuffle::tryPrepareForUnpack() {
6164 if (ZeroVecOpNo == UINT32_MAX ||
Ops.size() == 1)
6169 if (
Ops.size() > 2 &&
6174 UnpackFromEltSize = 1;
6175 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6176 bool MatchUnpack =
true;
6179 unsigned ToEltSize = UnpackFromEltSize * 2;
6180 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6183 if (Bytes[Elt] != -1) {
6185 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6186 MatchUnpack =
false;
6192 if (
Ops.size() == 2) {
6194 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6196 if (SrcBytes[i] == -1)
6198 if (SrcBytes[i] % 16 !=
int(i))
6199 CanUseUnpackHigh =
false;
6201 CanUseUnpackLow =
false;
6202 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6203 UnpackFromEltSize = UINT_MAX;
6207 if (!CanUseUnpackHigh)
6213 if (UnpackFromEltSize > 4)
6216 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6217 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6219 dumpBytes(Bytes,
"Original Bytes vector:"););
6228 Elt += UnpackFromEltSize;
6229 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6230 Bytes[
B] = Bytes[Elt];
6238 Ops.erase(&
Ops[ZeroVecOpNo]);
6240 if (Bytes[
I] >= 0) {
6242 if (OpNo > ZeroVecOpNo)
6253 if (!unpackWasPrepared())
6255 unsigned InBits = UnpackFromEltSize * 8;
6259 unsigned OutBits = InBits * 2;
6262 return DAG.
getNode(UnpackLow ? SystemZISD::UNPACKL_LOW
6263 : SystemZISD::UNPACKL_HIGH,
6264 DL, OutVT, PackedOp);
6269 for (
unsigned I = 1,
E =
Op.getNumOperands();
I !=
E; ++
I)
6270 if (!
Op.getOperand(
I).isUndef())
6286 if (
Value.isUndef())
6298 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op1);
6301 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Op0);
6302 return DAG.
getNode(SystemZISD::MERGE_HIGH,
DL, VT,
6323 return DAG.
getNode(SystemZISD::JOIN_DWORDS,
DL, MVT::v2i64, Op0, Op1);
6339 GeneralShuffle GS(VT);
6341 bool FoundOne =
false;
6342 for (
unsigned I = 0;
I < NumElements; ++
I) {
6345 Op =
Op.getOperand(0);
6348 unsigned Elem =
Op.getConstantOperandVal(1);
6349 if (!GS.add(
Op.getOperand(0), Elem))
6352 }
else if (
Op.isUndef()) {
6366 if (!ResidueOps.
empty()) {
6367 while (ResidueOps.
size() < NumElements)
6369 for (
auto &
Op : GS.Ops) {
6370 if (!
Op.getNode()) {
6376 return GS.getNode(DAG,
SDLoc(BVN));
6379bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6385 if (Subtarget.hasVectorEnhancements2() &&
Op.getOpcode() == SystemZISD::LRV)
6396 "Handling full vectors only.");
6416 if (Op01.
getOpcode() == SystemZISD::REPLICATE && Op01 == Op23)
6428 unsigned int NumElements = Elems.
size();
6429 unsigned int Count = 0;
6430 for (
auto Elem : Elems) {
6431 if (!Elem.isUndef()) {
6434 else if (Elem != Single) {
6454 if (
Single.getNode() && (
Count > 1 || isVectorElementLoad(Single)))
6455 return DAG.
getNode(SystemZISD::REPLICATE,
DL, VT, Single);
6458 bool AllLoads =
true;
6459 for (
auto Elem : Elems)
6460 if (!isVectorElementLoad(Elem)) {
6466 if (VT == MVT::v2i64 && !AllLoads)
6470 if (VT == MVT::v2f64 && !AllLoads)
6480 if (VT == MVT::v4f32 && !AllLoads)
6484 if (VT == MVT::v8f16 && !AllLoads) {
6493 if (Op0123.
getOpcode() == SystemZISD::REPLICATE && Op0123 == Op4567)
6502 unsigned NumConstants = 0;
6503 for (
unsigned I = 0;
I < NumElements; ++
I) {
6517 if (NumConstants > 0) {
6518 for (
unsigned I = 0;
I < NumElements; ++
I)
6529 std::map<const SDNode*, unsigned> UseCounts;
6530 SDNode *LoadMaxUses =
nullptr;
6531 for (
unsigned I = 0;
I < NumElements; ++
I)
6532 if (isVectorElementLoad(Elems[
I])) {
6533 SDNode *Ld = Elems[
I].getNode();
6534 unsigned Count = ++UseCounts[Ld];
6535 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] <
Count)
6538 if (LoadMaxUses !=
nullptr) {
6539 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6543 unsigned I1 = NumElements / 2 - 1;
6544 unsigned I2 = NumElements - 1;
6545 bool Def1 = !Elems[
I1].isUndef();
6546 bool Def2 = !Elems[I2].isUndef();
6560 for (
unsigned I = 0;
I < NumElements; ++
I)
6561 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6571 EVT VT =
Op.getValueType();
6573 if (BVN->isConstant()) {
6574 if (SystemZVectorConstantInfo(BVN).isVectorConstantLegal(Subtarget))
6592 for (
unsigned I = 0;
I < NumElements; ++
I)
6594 return buildVector(DAG,
DL, VT,
Ops);
6601 EVT VT =
Op.getValueType();
6604 if (VSN->isSplat()) {
6606 unsigned Index = VSN->getSplatIndex();
6608 "Splat index should be defined and in first operand");
6614 return DAG.
getNode(SystemZISD::SPLAT,
DL, VT,
Op.getOperand(0),
6618 GeneralShuffle
GS(VT);
6619 for (
unsigned I = 0;
I < NumElements; ++
I) {
6620 int Elt = VSN->getMaskElt(
I);
6623 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6624 unsigned(Elt) % NumElements))
6627 return GS.getNode(DAG, SDLoc(VSN));
6642 assert(
Op.getSimpleValueType() == MVT::i64 &&
6643 "Expexted to convert i64 to f16.");
6655 assert(
Op.getSimpleValueType() == MVT::f16 &&
6656 "Expected to convert f16 to i64.");
6673 EVT VT =
Op.getValueType();
6678 if (VT == MVT::v2f64 &&
6702SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6708 EVT VT =
Op.getValueType();
6713 uint64_t
Index = CIndexN->getZExtValue();
6722 MVT ExtrVT = IntVT == MVT::i16 ? MVT::i32 : IntVT;
6730SDValue SystemZTargetLowering::
6733 EVT OutVT =
Op.getValueType();
6737 unsigned StartOffset = 0;
6744 ArrayRef<int> ShuffleMask = SVN->
getMask();
6749 if (ToBits == 64 && OutNumElts == 2) {
6750 int NumElem = ToBits / FromBits;
6751 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6757 int StartOffsetCandidate = -1;
6758 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6759 if (ShuffleMask[Elt] == -1)
6761 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6762 if (StartOffsetCandidate == -1)
6763 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6764 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6767 StartOffsetCandidate = -1;
6770 if (StartOffsetCandidate != -1) {
6771 StartOffset = StartOffsetCandidate;
6780 unsigned Opcode = SystemZISD::UNPACK_HIGH;
6781 if (StartOffset >= OutNumElts) {
6782 Opcode = SystemZISD::UNPACK_LOW;
6783 StartOffset -= OutNumElts;
6785 PackedOp = DAG.
getNode(Opcode, SDLoc(PackedOp), OutVT, PackedOp);
6786 }
while (FromBits != ToBits);
6791SDValue SystemZTargetLowering::
6795 EVT OutVT =
Op.getValueType();
6799 unsigned NumInPerOut = InNumElts / OutNumElts;
6804 SmallVector<int, 16>
Mask(InNumElts);
6805 unsigned ZeroVecElt = InNumElts;
6806 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6807 unsigned MaskElt = PackedElt * NumInPerOut;
6808 unsigned End = MaskElt + NumInPerOut - 1;
6809 for (; MaskElt < End; MaskElt++)
6810 Mask[MaskElt] = ZeroVecElt++;
6811 Mask[MaskElt] = PackedElt;
6818 unsigned ByScalar)
const {
6823 EVT VT =
Op.getValueType();
6828 APInt SplatBits, SplatUndef;
6829 unsigned SplatBitSize;
6833 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6834 ElemBitSize,
true) &&
6835 SplatBitSize == ElemBitSize) {
6838 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6841 BitVector UndefElements;
6847 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6854 if (VSN->isSplat()) {
6855 SDValue VSNOp0 = VSN->getOperand(0);
6856 unsigned Index = VSN->getSplatIndex();
6858 "Splat index should be defined and in first operand");
6865 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6883 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6884 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6887 if (ShiftAmt > 120) {
6891 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6895 SmallVector<int, 16>
Mask(16);
6896 for (
unsigned Elt = 0; Elt < 16; Elt++)
6897 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6899 if ((ShiftAmt & 7) == 0)
6903 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Shuf1, Shuf2,
6921 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6922 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6925 if (ShiftAmt > 120) {
6929 DAG.
getNode(SystemZISD::SHL_DOUBLE_BIT,
DL, MVT::v16i8, Op0, Op1,
6933 SmallVector<int, 16>
Mask(16);
6934 for (
unsigned Elt = 0; Elt < 16; Elt++)
6935 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6937 if ((ShiftAmt & 7) == 0)
6941 DAG.
getNode(SystemZISD::SHR_DOUBLE_BIT,
DL, MVT::v16i8, Shuf2, Shuf1,
6953 MVT DstVT =
Op.getSimpleValueType();
6956 unsigned SrcAS =
N->getSrcAddressSpace();
6958 assert(SrcAS !=
N->getDestAddressSpace() &&
6959 "addrspacecast must be between different address spaces");
6967 }
else if (DstVT == MVT::i32) {
6981 if (
In.getSimpleValueType() != MVT::f16)
6988 SDValue Chain,
bool IsStrict)
const {
6989 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
6992 std::tie(Result, Chain) =
7001 bool IsStrict =
Op->isStrictFPOpcode();
7003 MVT VT =
Op.getSimpleValueType();
7004 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7012 if (!Subtarget.hasFPExtension() && !IsSigned)
7023 if (VT == MVT::i128) {
7026 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7036 bool IsStrict =
Op->isStrictFPOpcode();
7038 MVT VT =
Op.getSimpleValueType();
7039 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
7044 if (VT == MVT::f16) {
7051 if (!Subtarget.hasFPExtension() && !IsSigned)
7054 if (InVT == MVT::i128) {
7057 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
7066 EVT RegVT =
Op.getValueType();
7067 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
7074 assert(EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
7076 AtomicLd->getChain(), AtomicLd->getBasePtr(),
7077 AtomicLd->getMemOperand());
7097 Shft, AtomicSt->getBasePtr(),
7098 AtomicSt->getMemOperand());
7108 MVT ResultVT =
Op.getSimpleValueType();
7110 unsigned Check =
Op.getConstantOperandVal(1);
7112 unsigned TDCMask = 0;
7149 MachinePointerInfo MPI =
7155 SystemZISD::STCKF,
DL, DAG.
getVTList(MVT::Other), StoreOps, MVT::i64,
7159 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7164 switch (
Op.getOpcode()) {
7166 return lowerFRAMEADDR(
Op, DAG);
7168 return lowerRETURNADDR(
Op, DAG);
7170 return lowerBR_CC(
Op, DAG);
7172 return lowerSELECT_CC(
Op, DAG);
7174 return lowerSETCC(
Op, DAG);
7176 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7178 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7190 return lowerBITCAST(
Op, DAG);
7192 return lowerVASTART(
Op, DAG);
7194 return lowerVACOPY(
Op, DAG);
7196 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7198 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7200 return lowerMULH(
Op, DAG, SystemZISD::SMUL_LOHI);
7202 return lowerMULH(
Op, DAG, SystemZISD::UMUL_LOHI);
7204 return lowerSMUL_LOHI(
Op, DAG);
7206 return lowerUMUL_LOHI(
Op, DAG);
7208 return lowerSDIVREM(
Op, DAG);
7210 return lowerUDIVREM(
Op, DAG);
7215 return lowerXALUO(
Op, DAG);
7218 return lowerUADDSUBO_CARRY(
Op, DAG);
7220 return lowerOR(
Op, DAG);
7222 return lowerCTPOP(
Op, DAG);
7224 return lowerVECREDUCE_ADD(
Op, DAG);
7226 return lowerATOMIC_FENCE(
Op, DAG);
7228 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_SWAPW);
7230 return lowerATOMIC_STORE(
Op, DAG);
7232 return lowerATOMIC_LOAD(
Op, DAG);
7234 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_ADD);
7236 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7238 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_AND);
7240 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_OR);
7242 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_XOR);
7244 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_NAND);
7246 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MIN);
7248 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_MAX);
7250 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMIN);
7252 return lowerATOMIC_LOAD_OP(
Op, DAG, SystemZISD::ATOMIC_LOADW_UMAX);
7254 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7256 return lowerSTACKSAVE(
Op, DAG);
7258 return lowerSTACKRESTORE(
Op, DAG);
7260 return lowerPREFETCH(
Op, DAG);
7262 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7264 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7266 return lowerBUILD_VECTOR(
Op, DAG);
7268 return lowerVECTOR_SHUFFLE(
Op, DAG);
7270 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7272 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7274 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7276 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7278 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7280 return lowerShift(
Op, DAG, SystemZISD::VSHL_BY_SCALAR);
7282 return lowerShift(
Op, DAG, SystemZISD::VSRL_BY_SCALAR);
7284 return lowerShift(
Op, DAG, SystemZISD::VSRA_BY_SCALAR);
7288 return lowerShift(
Op, DAG, SystemZISD::VROTL_BY_SCALAR);
7290 return lowerFSHL(
Op, DAG);
7292 return lowerFSHR(
Op, DAG);
7295 return lowerFP_EXTEND(
Op, DAG);
7300 return lower_FP_TO_INT(
Op, DAG);
7305 return lower_INT_TO_FP(
Op, DAG);
7307 return lowerLoadF16(
Op, DAG);
7309 return lowerStoreF16(
Op, DAG);
7311 return lowerIS_FPCLASS(
Op, DAG);
7313 return lowerGET_ROUNDING(
Op, DAG);
7315 return lowerREADCYCLECOUNTER(
Op, DAG);
7337 &SystemZ::FP128BitRegClass);
7346 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7361 &SystemZ::FP128BitRegClass);
7378 switch (
N->getOpcode()) {
7382 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7385 DL, Tys,
Ops, MVT::i128, MMO);
7388 if (
N->getValueType(0) == MVT::f128)
7402 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7405 DL, Tys,
Ops, MVT::i128, MMO);
7411 MVT::Other, Res), 0);
7423 DL, Tys,
Ops, MVT::i128, MMO);
7437 EVT SrcVT = Src.getValueType();
7438 EVT ResVT =
N->getValueType(0);
7439 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7441 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7442 if (Subtarget.hasVector()) {
7450 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7452 Subtarget.hasVector()
7466 bool IsStrict =
N->isStrictFPOpcode();
7468 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7469 EVT ResVT =
N->getValueType(0);
7471 if (ResVT == MVT::f16) {
7494 bool IsStrict =
N->isStrictFPOpcode();
7496 EVT ResVT =
N->getValueType(0);
7497 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7500 if (InVT == MVT::f16) {
7506 std::tie(InF32, Chain) =
7531bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7532 if (!Subtarget.hasVector())
7546 DAGCombinerInfo &DCI,
7554 unsigned Opcode =
Op.getOpcode();
7557 Op =
Op.getOperand(0);
7559 canTreatAsByteVector(
Op.getValueType())) {
7568 BytesPerElement,
First))
7575 if (Byte % BytesPerElement != 0)
7578 Index = Byte / BytesPerElement;
7582 canTreatAsByteVector(
Op.getValueType())) {
7585 EVT OpVT =
Op.getValueType();
7587 if (OpBytesPerElement < BytesPerElement)
7591 unsigned End = (
Index + 1) * BytesPerElement;
7592 if (End % OpBytesPerElement != 0)
7595 Op =
Op.getOperand(End / OpBytesPerElement - 1);
7596 if (!
Op.getValueType().isInteger()) {
7599 DCI.AddToWorklist(
Op.getNode());
7604 DCI.AddToWorklist(
Op.getNode());
7611 canTreatAsByteVector(
Op.getValueType()) &&
7612 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7614 EVT ExtVT =
Op.getValueType();
7615 EVT OpVT =
Op.getOperand(0).getValueType();
7618 unsigned Byte =
Index * BytesPerElement;
7619 unsigned SubByte =
Byte % ExtBytesPerElement;
7620 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7621 if (SubByte < MinSubByte ||
7622 SubByte + BytesPerElement > ExtBytesPerElement)
7625 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7627 Byte += SubByte - MinSubByte;
7628 if (Byte % BytesPerElement != 0)
7630 Op =
Op.getOperand(0);
7637 if (
Op.getValueType() != VecVT) {
7639 DCI.AddToWorklist(
Op.getNode());
7649SDValue SystemZTargetLowering::combineTruncateExtract(
7658 if (canTreatAsByteVector(VecVT)) {
7662 if (BytesPerElement % TruncBytes == 0) {
7668 unsigned Scale = BytesPerElement / TruncBytes;
7669 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7676 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7677 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7685SDValue SystemZTargetLowering::combineZERO_EXTEND(
7686 SDNode *
N, DAGCombinerInfo &DCI)
const {
7688 SelectionDAG &DAG = DCI.DAG;
7690 EVT VT =
N->getValueType(0);
7691 if (N0.
getOpcode() == SystemZISD::SELECT_CCMASK) {
7694 if (TrueOp && FalseOp) {
7704 DCI.CombineTo(N0.
getNode(), TruncSelect);
7747 return DAG.
getNode(SystemZISD::VSCBI, SDLoc(N0), VT, Op0, Op1);
7765SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7766 SDNode *
N, DAGCombinerInfo &DCI)
const {
7770 SelectionDAG &DAG = DCI.DAG;
7772 EVT VT =
N->getValueType(0);
7786SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7787 SDNode *
N, DAGCombinerInfo &DCI)
const {
7791 SelectionDAG &DAG = DCI.DAG;
7793 EVT VT =
N->getValueType(0);
7800 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7801 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7817SDValue SystemZTargetLowering::combineMERGE(
7818 SDNode *
N, DAGCombinerInfo &DCI)
const {
7819 SelectionDAG &DAG = DCI.DAG;
7820 unsigned Opcode =
N->getOpcode();
7828 if (Op1 ==
N->getOperand(0))
7833 if (ElemBytes <= 4) {
7834 Opcode = (Opcode == SystemZISD::MERGE_HIGH ?
7835 SystemZISD::UNPACKL_HIGH : SystemZISD::UNPACKL_LOW);
7841 DCI.AddToWorklist(Op1.
getNode());
7844 DCI.AddToWorklist(
Op.getNode());
7853 LoPart = HiPart =
nullptr;
7858 if (
Use.getResNo() != 0)
7863 bool IsLoPart =
true;
7888 LoPart = HiPart =
nullptr;
7893 if (
Use.getResNo() != 0)
7899 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7902 switch (
User->getConstantOperandVal(1)) {
7903 case SystemZ::subreg_l64:
7908 case SystemZ::subreg_h64:
7920SDValue SystemZTargetLowering::combineLOAD(
7921 SDNode *
N, DAGCombinerInfo &DCI)
const {
7922 SelectionDAG &DAG = DCI.DAG;
7923 EVT LdVT =
N->getValueType(0);
7927 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7928 if (PtrVT != LoadNodeVT) {
7932 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7933 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7934 LN->getMemOperand());
7944 SDNode *LoPart, *HiPart;
7952 LD->getPointerInfo(),
LD->getBaseAlign(),
7953 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7955 DCI.CombineTo(HiPart, EltLoad,
true);
7962 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7963 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7965 DCI.CombineTo(LoPart, EltLoad,
true);
7972 DCI.AddToWorklist(Chain.
getNode());
7987 for (SDUse &Use :
N->uses()) {
7988 if (
Use.getUser()->getOpcode() == SystemZISD::REPLICATE) {
7992 }
else if (
Use.getResNo() == 0)
7995 if (!Replicate || OtherUses.
empty())
8001 for (SDNode *U : OtherUses) {
8004 Ops.push_back((
Op.getNode() ==
N &&
Op.getResNo() == 0) ? Extract0 :
Op);
8010bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8011 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8013 if (Subtarget.hasVectorEnhancements2())
8014 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8026 for (
unsigned i = 0; i < NumElts; ++i) {
8027 if (M[i] < 0)
continue;
8028 if ((
unsigned) M[i] != NumElts - 1 - i)
8036 for (
auto *U : StoredVal->
users()) {
8038 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8097SDValue SystemZTargetLowering::combineSTORE(
8098 SDNode *
N, DAGCombinerInfo &DCI)
const {
8099 SelectionDAG &DAG = DCI.DAG;
8102 EVT MemVT = SN->getMemoryVT();
8106 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8107 if (PtrVT != StoreNodeVT) {
8111 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8112 SN->getPointerInfo(), SN->getBaseAlign(),
8113 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8121 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8123 combineTruncateExtract(SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8124 DCI.AddToWorklist(
Value.getNode());
8128 SN->getBasePtr(), SN->getMemoryVT(),
8129 SN->getMemOperand());
8133 if (!SN->isTruncatingStore() &&
8149 Ops, MemVT, SN->getMemOperand());
8152 if (!SN->isTruncatingStore() &&
8155 Subtarget.hasVectorEnhancements2()) {
8157 ArrayRef<int> ShuffleMask = SVN->
getMask();
8165 Ops, MemVT, SN->getMemOperand());
8170 if (!SN->isTruncatingStore() &&
8173 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8177 Ops, MemVT, SN->getMemOperand());
8187 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8188 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8190 SN->getChain(),
DL, LoPart,
8192 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8193 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8211 auto FindReplicatedImm = [&](ConstantSDNode *
C,
unsigned TotBytes) {
8213 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8217 APInt Val =
C->getAPIntValue();
8220 assert(SN->isTruncatingStore() &&
8221 "Non-truncating store and immediate value does not fit?");
8222 Val = Val.
trunc(TotBytes * 8);
8225 SystemZVectorConstantInfo VCI(APInt(TotBytes * 8, Val.
getZExtValue()));
8226 if (VCI.isVectorConstantLegal(Subtarget) &&
8227 VCI.Opcode == SystemZISD::REPLICATE) {
8235 auto FindReplicatedReg = [&](
SDValue MulOp) {
8236 EVT MulVT = MulOp.getValueType();
8237 if (MulOp->getOpcode() ==
ISD::MUL &&
8238 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8242 WordVT =
LHS->getOperand(0).getValueType();
8249 SystemZVectorConstantInfo VCI(
8251 if (VCI.isVectorConstantLegal(Subtarget) &&
8252 VCI.Opcode == SystemZISD::REPLICATE && VCI.OpVals[0] == 1 &&
8253 WordVT == VCI.VecVT.getScalarType())
8265 FindReplicatedReg(SplatVal);
8270 FindReplicatedReg(Op1);
8275 "Bad type handling");
8279 return DAG.
getStore(SN->getChain(), SDLoc(SN), SplatVal,
8280 SN->getBasePtr(), SN->getMemOperand());
8287SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8288 SDNode *
N, DAGCombinerInfo &DCI)
const {
8289 SelectionDAG &DAG = DCI.DAG;
8292 N->getOperand(0).hasOneUse() &&
8293 Subtarget.hasVectorEnhancements2()) {
8295 ArrayRef<int> ShuffleMask = SVN->
getMask();
8308 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8312 DCI.CombineTo(
N, ESLoad);
8316 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8326SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8327 SDNode *
N, DAGCombinerInfo &DCI)
const {
8328 SelectionDAG &DAG = DCI.DAG;
8330 if (!Subtarget.hasVector())
8336 Op.getValueType().isVector() &&
8337 Op.getOperand(0).getValueType().isVector() &&
8338 Op.getValueType().getVectorNumElements() ==
8339 Op.getOperand(0).getValueType().getVectorNumElements())
8340 Op =
Op.getOperand(0);
8344 EVT VecVT =
Op.getValueType();
8347 Op.getOperand(0),
N->getOperand(1));
8348 DCI.AddToWorklist(
Op.getNode());
8350 if (EltVT !=
N->getValueType(0)) {
8351 DCI.AddToWorklist(
Op.getNode());
8361 if (canTreatAsByteVector(VecVT))
8362 return combineExtract(SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8363 IndexN->getZExtValue(), DCI,
false);
8368SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8369 SDNode *
N, DAGCombinerInfo &DCI)
const {
8370 SelectionDAG &DAG = DCI.DAG;
8372 if (
N->getOperand(0) ==
N->getOperand(1))
8373 return DAG.
getNode(SystemZISD::REPLICATE, SDLoc(
N),
N->getValueType(0),
8383 if (Chain1 == Chain2)
8391SDValue SystemZTargetLowering::combineFP_ROUND(
8392 SDNode *
N, DAGCombinerInfo &DCI)
const {
8394 if (!Subtarget.hasVector())
8403 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8404 SelectionDAG &DAG = DCI.DAG;
8406 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8412 for (
auto *U : Vec->
users()) {
8413 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8415 U->getOperand(0) == Vec &&
8417 U->getConstantOperandVal(1) == 1) {
8419 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8423 if (
N->isStrictFPOpcode()) {
8427 VRound = DAG.
getNode(SystemZISD::STRICT_VROUND, SDLoc(
N),
8428 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8431 VRound = DAG.
getNode(SystemZISD::VROUND, SDLoc(
N),
8433 DCI.AddToWorklist(VRound.
getNode());
8437 DCI.AddToWorklist(Extract1.
getNode());
8443 VRound, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8446 N->getVTList(), Extract0, Chain);
8455SDValue SystemZTargetLowering::combineFP_EXTEND(
8456 SDNode *
N, DAGCombinerInfo &DCI)
const {
8458 if (!Subtarget.hasVector())
8467 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8468 SelectionDAG &DAG = DCI.DAG;
8470 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8476 for (
auto *U : Vec->
users()) {
8477 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8479 U->getOperand(0) == Vec &&
8481 U->getConstantOperandVal(1) == 2) {
8483 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8487 if (
N->isStrictFPOpcode()) {
8491 VExtend = DAG.
getNode(SystemZISD::STRICT_VEXTEND, SDLoc(
N),
8492 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8495 VExtend = DAG.
getNode(SystemZISD::VEXTEND, SDLoc(
N),
8497 DCI.AddToWorklist(VExtend.
getNode());
8501 DCI.AddToWorklist(Extract1.
getNode());
8507 VExtend, DAG.
getConstant(0, SDLoc(Op0), MVT::i32));
8510 N->getVTList(), Extract0, Chain);
8519SDValue SystemZTargetLowering::combineINT_TO_FP(
8520 SDNode *
N, DAGCombinerInfo &DCI)
const {
8523 SelectionDAG &DAG = DCI.DAG;
8525 unsigned Opcode =
N->getOpcode();
8526 EVT OutVT =
N->getValueType(0);
8530 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8536 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8537 OutScalarBits <= 64) {
8541 unsigned ExtOpcode =
8544 return DAG.
getNode(Opcode, SDLoc(
N), OutVT, ExtOp);
8549SDValue SystemZTargetLowering::combineFCOPYSIGN(
8550 SDNode *
N, DAGCombinerInfo &DCI)
const {
8551 SelectionDAG &DAG = DCI.DAG;
8552 EVT VT =
N->getValueType(0);
8565SDValue SystemZTargetLowering::combineBSWAP(
8566 SDNode *
N, DAGCombinerInfo &DCI)
const {
8567 SelectionDAG &DAG = DCI.DAG;
8570 N->getOperand(0).hasOneUse() &&
8571 canLoadStoreByteSwapped(
N->getValueType(0))) {
8580 EVT LoadVT =
N->getValueType(0);
8581 if (LoadVT == MVT::i16)
8586 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8590 if (
N->getValueType(0) == MVT::i16)
8595 DCI.CombineTo(
N, ResVal);
8599 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8608 Op.getValueType().isVector() &&
8609 Op.getOperand(0).getValueType().isVector() &&
8610 Op.getValueType().getVectorNumElements() ==
8611 Op.getOperand(0).getValueType().getVectorNumElements())
8612 Op =
Op.getOperand(0);
8624 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8626 EVT VecVT =
N->getValueType(0);
8630 DCI.AddToWorklist(Vec.
getNode());
8634 DCI.AddToWorklist(Elt.
getNode());
8637 DCI.AddToWorklist(Vec.
getNode());
8639 DCI.AddToWorklist(Elt.
getNode());
8647 if (SV &&
Op.hasOneUse()) {
8655 EVT VecVT =
N->getValueType(0);
8658 DCI.AddToWorklist(Op0.
getNode());
8662 DCI.AddToWorklist(Op1.
getNode());
8665 DCI.AddToWorklist(Op0.
getNode());
8667 DCI.AddToWorklist(Op1.
getNode());
8675SDValue SystemZTargetLowering::combineSETCC(
8676 SDNode *
N, DAGCombinerInfo &DCI)
const {
8677 SelectionDAG &DAG = DCI.DAG;
8683 EVT VT =
N->getValueType(0);
8693 Src.getValueType().isFixedLengthVector() &&
8694 Src.getValueType().getScalarType() == MVT::i1) {
8695 EVT CmpVT = Src.getOperand(0).getValueType();
8715 case SystemZISD::IPM:
8720 case SystemZISD::SELECT_CCMASK: {
8722 if (Op4CCReg.
getOpcode() == SystemZISD::ICMP ||
8723 Op4CCReg.
getOpcode() == SystemZISD::TM) {
8726 return std::make_pair(OpCC, OpCCValid);
8731 int CCValidVal = CCValid->getZExtValue();
8732 return std::make_pair(Op4CCReg, CCValidVal);
8743 return std::make_pair(Op0CC, Op0CCValid);
8759 return {Val, Val, Val, Val};
8760 case SystemZISD::IPM: {
8765 for (
auto CC : {0, 1, 2, 3})
8768 return ShiftedCCVals;
8770 case SystemZISD::SELECT_CCMASK: {
8774 if (!CCValid || !CCMask)
8777 int CCValidVal = CCValid->getZExtValue();
8778 int CCMaskVal = CCMask->getZExtValue();
8788 if (TrueSDVals.empty() || FalseSDVals.empty())
8791 for (
auto &CCVal : {0, 1, 2, 3})
8792 MergedSDVals.
emplace_back(((CCMaskVal & (1 << (3 - CCVal))) != 0)
8794 : FalseSDVals[CCVal]);
8795 return MergedSDVals;
8812 if (Op0SDVals.empty() || Op1SDVals.empty())
8815 for (
auto CCVal : {0, 1, 2, 3})
8817 Opcode,
DL, Val.
getValueType(), Op0SDVals[CCVal], Op1SDVals[CCVal]));
8818 return BinaryOpSDVals;
8829 auto *CCNode = CCReg.
getNode();
8833 if (CCNode->getOpcode() == SystemZISD::TM) {
8836 auto emulateTMCCMask = [](
const SDValue &Op0Val,
const SDValue &Op1Val) {
8839 if (!Op0Node || !Op1Node)
8841 auto Op0APVal = Op0Node->getAPIntValue();
8842 auto Op1APVal = Op1Node->getAPIntValue();
8843 auto Result = Op0APVal & Op1APVal;
8844 bool AllOnes = Result == Op1APVal;
8845 bool AllZeros = Result == 0;
8846 bool IsLeftMostBitSet = Result[Op1APVal.getActiveBits()] != 0;
8847 return AllZeros ? 0 :
AllOnes ? 3 : IsLeftMostBitSet ? 2 : 1;
8851 auto [Op0CC, Op0CCValid] =
findCCUse(Op0);
8856 if (Op0SDVals.empty() || Op1SDVals.empty())
8859 for (
auto CC : {0, 1, 2, 3}) {
8860 auto CCVal = emulateTMCCMask(Op0SDVals[CC], Op1SDVals[CC]);
8864 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8866 NewCCMask &= Op0CCValid;
8869 CCValid = Op0CCValid;
8872 if (CCNode->getOpcode() != SystemZISD::ICMP ||
8879 auto [Op0CC, Op0CCValid] =
findCCUse(CmpOp0);
8883 if (Op0SDVals.empty() || Op1SDVals.empty())
8887 auto CmpTypeVal = CmpType->getZExtValue();
8888 const auto compareCCSigned = [&CmpTypeVal](
const SDValue &Op0Val,
8892 if (!Op0Node || !Op1Node)
8894 auto Op0APVal = Op0Node->getAPIntValue();
8895 auto Op1APVal = Op1Node->getAPIntValue();
8897 return Op0APVal == Op1APVal ? 0 : Op0APVal.slt(Op1APVal) ? 1 : 2;
8898 return Op0APVal == Op1APVal ? 0 : Op0APVal.ult(Op1APVal) ? 1 : 2;
8901 for (
auto CC : {0, 1, 2, 3}) {
8902 auto CCVal = compareCCSigned(Op0SDVals[CC], Op1SDVals[CC]);
8906 NewCCMask |= (CCMask & (1 << (3 - CCVal))) != 0;
8908 NewCCMask &= Op0CCValid;
8911 CCValid = Op0CCValid;
8922 const Value *Rhs)
const {
8923 const auto isFlagOutOpCC = [](
const Value *V) {
8925 const Value *RHSVal;
8932 if (CB->isInlineAsm()) {
8934 return IA && IA->getConstraintString().contains(
"{@cc}");
8945 if (isFlagOutOpCC(Lhs) && isFlagOutOpCC(Rhs))
8948 return {-1, -1, -1};
8952 DAGCombinerInfo &DCI)
const {
8958 if (!CCValid || !CCMask)
8961 int CCValidVal = CCValid->getZExtValue();
8962 int CCMaskVal = CCMask->getZExtValue();
8969 if (
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
8970 CCMaskVal != CCValidVal)
8971 return DAG.
getNode(SystemZISD::BR_CCMASK,
SDLoc(
N),
N->getValueType(0),
8975 N->getOperand(3), CCReg);
8979SDValue SystemZTargetLowering::combineSELECT_CCMASK(
8980 SDNode *
N, DAGCombinerInfo &DCI)
const {
8986 if (!CCValid || !CCMask)
8989 int CCValidVal = CCValid->getZExtValue();
8990 int CCMaskVal = CCMask->getZExtValue();
8993 bool IsCombinedCCReg =
combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG);
8997 const auto constructCCSDValsFromSELECT = [&CCReg](
SDValue &Val) {
8998 if (Val.getOpcode() == SystemZISD::SELECT_CCMASK) {
9000 if (Val.getOperand(4) != CCReg)
9007 int CCMaskVal = CCMask->getZExtValue();
9008 for (
auto &CC : {0, 1, 2, 3})
9009 Res.
emplace_back(((CCMaskVal & (1 << (3 - CC))) != 0) ? TrueVal
9023 if (TrueSDVals.empty())
9024 TrueSDVals = constructCCSDValsFromSELECT(TrueVal);
9025 if (FalseSDVals.empty())
9026 FalseSDVals = constructCCSDValsFromSELECT(FalseVal);
9027 if (!TrueSDVals.empty() && !FalseSDVals.empty()) {
9028 SmallSet<SDValue, 4> MergedSDValsSet;
9030 for (
auto CC : {0, 1, 2, 3}) {
9031 if ((CCValidVal & ((1 << (3 - CC)))) != 0)
9032 MergedSDValsSet.
insert(((CCMaskVal & (1 << (3 - CC))) != 0)
9036 if (MergedSDValsSet.
size() == 1)
9037 return *MergedSDValsSet.
begin();
9038 if (MergedSDValsSet.
size() == 2) {
9039 auto BeginIt = MergedSDValsSet.
begin();
9040 SDValue NewTrueVal = *BeginIt, NewFalseVal = *next(BeginIt);
9041 if (NewTrueVal == FalseVal || NewFalseVal == TrueVal)
9044 for (
auto CC : {0, 1, 2, 3}) {
9046 NewCCMask |= ((CCMaskVal & (1 << (3 - CC))) != 0)
9047 ? (TrueSDVals[CC] == NewTrueVal)
9048 : (FalseSDVals[CC] == NewTrueVal);
9050 CCMaskVal = NewCCMask;
9051 CCMaskVal &= CCValidVal;
9054 IsCombinedCCReg =
true;
9062 if (CCMaskVal == CCValidVal)
9065 if (IsCombinedCCReg)
9067 SystemZISD::SELECT_CCMASK, SDLoc(
N),
N->getValueType(0), TrueVal,
9074SDValue SystemZTargetLowering::combineGET_CCMASK(
9075 SDNode *
N, DAGCombinerInfo &DCI)
const {
9080 if (!CCValid || !CCMask)
9082 int CCValidVal = CCValid->getZExtValue();
9083 int CCMaskVal = CCMask->getZExtValue();
9088 if (
Select->getOpcode() != SystemZISD::SELECT_CCMASK)
9093 if (!SelectCCValid || !SelectCCMask)
9095 int SelectCCValidVal = SelectCCValid->getZExtValue();
9096 int SelectCCMaskVal = SelectCCMask->getZExtValue();
9100 if (!TrueVal || !FalseVal)
9104 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
9105 SelectCCMaskVal ^= SelectCCValidVal;
9109 if (SelectCCValidVal & ~CCValidVal)
9111 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
9114 return Select->getOperand(4);
9117SDValue SystemZTargetLowering::combineIntDIVREM(
9118 SDNode *
N, DAGCombinerInfo &DCI)
const {
9119 SelectionDAG &DAG = DCI.DAG;
9120 EVT VT =
N->getValueType(0);
9137SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
9138 SDNode *
N, DAGCombinerInfo &DCI)
const {
9139 SelectionDAG &DAG = DCI.DAG;
9143 "SRL or SRA node is required here!");
9145 if (!Subtarget.hasVector())
9155 SDValue ShiftOperand =
N->getOperand(0);
9175 if (!IsSignExt && !IsZeroExt)
9183 unsigned ActiveBits = IsSignExt
9184 ?
Constant->getAPIntValue().getSignificantBits()
9185 :
Constant->getAPIntValue().getActiveBits();
9186 if (ActiveBits > NarrowVTSize)
9202 unsigned ActiveBits = IsSignExt
9203 ?
Constant->getAPIntValue().getSignificantBits()
9204 :
Constant->getAPIntValue().getActiveBits();
9205 if (ActiveBits > NarrowVTSize)
9222 "Cannot have a multiply node with two different operand types.");
9224 "Cannot have an add node with two different operand types.");
9235 if (ShiftAmt != NarrowVTSize)
9239 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9240 NarrowVT == MVT::v4i32 ||
9241 (Subtarget.hasVectorEnhancements3() &&
9242 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9248 MulhRightOp, MulhAddOp);
9249 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9260 EVT VT =
Op.getValueType();
9269 Op =
Op.getOperand(0);
9270 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9274 bool CanUseEven =
true, CanUseOdd =
true;
9275 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9276 if (ShuffleMask[Elt] == -1)
9278 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9280 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9283 Op =
Op.getOperand(0);
9285 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9287 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9293 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9297 Op =
Op.getOperand(0);
9299 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9301 unsigned Elem =
Op.getConstantOperandVal(1);
9302 Op =
Op.getOperand(0);
9304 return IsSigned ? SystemZISD::VME : SystemZISD::VMLE;
9306 return IsSigned ? SystemZISD::VMO : SystemZISD::VMLO;
9313SDValue SystemZTargetLowering::combineMUL(
9314 SDNode *
N, DAGCombinerInfo &DCI)
const {
9315 SelectionDAG &DAG = DCI.DAG;
9322 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9323 return DAG.
getNode(OpcodeCand0, SDLoc(
N),
N->getValueType(0), Op0, Op1);
9328SDValue SystemZTargetLowering::combineINTRINSIC(
9329 SDNode *
N, DAGCombinerInfo &DCI)
const {
9330 SelectionDAG &DAG = DCI.DAG;
9332 unsigned Id =
N->getConstantOperandVal(1);
9336 case Intrinsic::s390_vll:
9337 case Intrinsic::s390_vlrl:
9339 if (
C->getZExtValue() >= 15)
9340 return DAG.
getLoad(
N->getValueType(0), SDLoc(
N),
N->getOperand(0),
9341 N->getOperand(3), MachinePointerInfo());
9344 case Intrinsic::s390_vstl:
9345 case Intrinsic::s390_vstrl:
9347 if (
C->getZExtValue() >= 15)
9348 return DAG.
getStore(
N->getOperand(0), SDLoc(
N),
N->getOperand(2),
9349 N->getOperand(4), MachinePointerInfo());
9357 if (
N->getOpcode() == SystemZISD::PCREL_WRAPPER)
9364 switch(
N->getOpcode()) {
9369 case SystemZISD::MERGE_HIGH:
9370 case SystemZISD::MERGE_LOW:
return combineMERGE(
N, DCI);
9375 case SystemZISD::JOIN_DWORDS:
return combineJOIN_DWORDS(
N, DCI);
9385 case SystemZISD::BR_CCMASK:
return combineBR_CCMASK(
N, DCI);
9386 case SystemZISD::SELECT_CCMASK:
return combineSELECT_CCMASK(
N, DCI);
9389 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9390 case ISD::MUL:
return combineMUL(
N, DCI);
9394 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9406 EVT VT =
Op.getValueType();
9409 unsigned Opcode =
Op.getOpcode();
9411 unsigned Id =
Op.getConstantOperandVal(0);
9413 case Intrinsic::s390_vpksh:
9414 case Intrinsic::s390_vpksf:
9415 case Intrinsic::s390_vpksg:
9416 case Intrinsic::s390_vpkshs:
9417 case Intrinsic::s390_vpksfs:
9418 case Intrinsic::s390_vpksgs:
9419 case Intrinsic::s390_vpklsh:
9420 case Intrinsic::s390_vpklsf:
9421 case Intrinsic::s390_vpklsg:
9422 case Intrinsic::s390_vpklshs:
9423 case Intrinsic::s390_vpklsfs:
9424 case Intrinsic::s390_vpklsgs:
9426 SrcDemE = DemandedElts;
9429 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9432 case Intrinsic::s390_vuphb:
9433 case Intrinsic::s390_vuphh:
9434 case Intrinsic::s390_vuphf:
9435 case Intrinsic::s390_vuplhb:
9436 case Intrinsic::s390_vuplhh:
9437 case Intrinsic::s390_vuplhf:
9438 SrcDemE =
APInt(NumElts * 2, 0);
9441 case Intrinsic::s390_vuplb:
9442 case Intrinsic::s390_vuplhw:
9443 case Intrinsic::s390_vuplf:
9444 case Intrinsic::s390_vupllb:
9445 case Intrinsic::s390_vupllh:
9446 case Intrinsic::s390_vupllf:
9447 SrcDemE =
APInt(NumElts * 2, 0);
9450 case Intrinsic::s390_vpdi: {
9452 SrcDemE =
APInt(NumElts, 0);
9453 if (!DemandedElts[OpNo - 1])
9455 unsigned Mask =
Op.getConstantOperandVal(3);
9456 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9458 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9461 case Intrinsic::s390_vsldb: {
9463 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9464 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9465 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9466 unsigned NumSrc0Els = 16 - FirstIdx;
9467 SrcDemE =
APInt(NumElts, 0);
9469 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9472 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9477 case Intrinsic::s390_vperm:
9486 case SystemZISD::JOIN_DWORDS:
9488 SrcDemE =
APInt(1, 1);
9490 case SystemZISD::SELECT_CCMASK:
9491 SrcDemE = DemandedElts;
9502 const APInt &DemandedElts,
9517 const APInt &DemandedElts,
9519 unsigned Depth)
const {
9523 unsigned Tmp0, Tmp1;
9528 EVT VT =
Op.getValueType();
9529 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9532 "KnownBits does not match VT in bitwidth");
9535 "DemandedElts does not match VT number of elements");
9537 unsigned Opcode =
Op.getOpcode();
9539 bool IsLogical =
false;
9540 unsigned Id =
Op.getConstantOperandVal(0);
9542 case Intrinsic::s390_vpksh:
9543 case Intrinsic::s390_vpksf:
9544 case Intrinsic::s390_vpksg:
9545 case Intrinsic::s390_vpkshs:
9546 case Intrinsic::s390_vpksfs:
9547 case Intrinsic::s390_vpksgs:
9548 case Intrinsic::s390_vpklsh:
9549 case Intrinsic::s390_vpklsf:
9550 case Intrinsic::s390_vpklsg:
9551 case Intrinsic::s390_vpklshs:
9552 case Intrinsic::s390_vpklsfs:
9553 case Intrinsic::s390_vpklsgs:
9554 case Intrinsic::s390_vpdi:
9555 case Intrinsic::s390_vsldb:
9556 case Intrinsic::s390_vperm:
9559 case Intrinsic::s390_vuplhb:
9560 case Intrinsic::s390_vuplhh:
9561 case Intrinsic::s390_vuplhf:
9562 case Intrinsic::s390_vupllb:
9563 case Intrinsic::s390_vupllh:
9564 case Intrinsic::s390_vupllf:
9567 case Intrinsic::s390_vuphb:
9568 case Intrinsic::s390_vuphh:
9569 case Intrinsic::s390_vuphf:
9570 case Intrinsic::s390_vuplb:
9571 case Intrinsic::s390_vuplhw:
9572 case Intrinsic::s390_vuplf: {
9587 case SystemZISD::JOIN_DWORDS:
9588 case SystemZISD::SELECT_CCMASK:
9591 case SystemZISD::REPLICATE: {
9614 if (
LHS == 1)
return 1;
9617 if (
RHS == 1)
return 1;
9618 unsigned Common = std::min(
LHS,
RHS);
9619 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9620 EVT VT =
Op.getValueType();
9622 if (SrcBitWidth > VTBits) {
9623 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9624 if (Common > SrcExtraBits)
9625 return (Common - SrcExtraBits);
9628 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9635 unsigned Depth)
const {
9636 if (
Op.getResNo() != 0)
9638 unsigned Opcode =
Op.getOpcode();
9640 unsigned Id =
Op.getConstantOperandVal(0);
9642 case Intrinsic::s390_vpksh:
9643 case Intrinsic::s390_vpksf:
9644 case Intrinsic::s390_vpksg:
9645 case Intrinsic::s390_vpkshs:
9646 case Intrinsic::s390_vpksfs:
9647 case Intrinsic::s390_vpksgs:
9648 case Intrinsic::s390_vpklsh:
9649 case Intrinsic::s390_vpklsf:
9650 case Intrinsic::s390_vpklsg:
9651 case Intrinsic::s390_vpklshs:
9652 case Intrinsic::s390_vpklsfs:
9653 case Intrinsic::s390_vpklsgs:
9654 case Intrinsic::s390_vpdi:
9655 case Intrinsic::s390_vsldb:
9656 case Intrinsic::s390_vperm:
9658 case Intrinsic::s390_vuphb:
9659 case Intrinsic::s390_vuphh:
9660 case Intrinsic::s390_vuphf:
9661 case Intrinsic::s390_vuplb:
9662 case Intrinsic::s390_vuplhw:
9663 case Intrinsic::s390_vuplf: {
9667 EVT VT =
Op.getValueType();
9677 case SystemZISD::SELECT_CCMASK:
9691 switch (
Op->getOpcode()) {
9692 case SystemZISD::PCREL_WRAPPER:
9693 case SystemZISD::PCREL_OFFSET:
9704 "Unexpected stack alignment");
9707 unsigned StackProbeSize =
9710 StackProbeSize &= ~(StackAlign - 1);
9711 return StackProbeSize ? StackProbeSize : StackAlign;
9728 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9734 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9750 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9752 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9758 if (miI ==
MBB->end()) {
9760 if (Succ->isLiveIn(SystemZ::CC))
9771 switch (
MI.getOpcode()) {
9772 case SystemZ::Select32:
9773 case SystemZ::Select64:
9774 case SystemZ::Select128:
9775 case SystemZ::SelectF32:
9776 case SystemZ::SelectF64:
9777 case SystemZ::SelectF128:
9778 case SystemZ::SelectVR32:
9779 case SystemZ::SelectVR64:
9780 case SystemZ::SelectVR128:
9812 for (
auto *
MI : Selects) {
9813 Register DestReg =
MI->getOperand(0).getReg();
9814 Register TrueReg =
MI->getOperand(1).getReg();
9815 Register FalseReg =
MI->getOperand(2).getReg();
9820 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9823 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9824 TrueReg = It->second.first;
9826 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9827 FalseReg = It->second.second;
9830 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9835 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9846 auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
9847 assert(TFL->hasReservedCallFrame(MF) &&
9848 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9853 uint32_t NumBytes =
MI.getOperand(0).getImm();
9858 MI.eraseFromParent();
9867 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9869 unsigned CCValid =
MI.getOperand(3).getImm();
9870 unsigned CCMask =
MI.getOperand(4).getImm();
9875 SmallVector<MachineInstr*, 8> Selects;
9876 SmallVector<MachineInstr*, 8> DbgValues;
9882 assert(NextMI.getOperand(3).getImm() == CCValid &&
9883 "Bad CCValid operands since CC was not redefined.");
9884 if (NextMI.getOperand(4).getImm() == CCMask ||
9885 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9891 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9892 NextMI.usesCustomInsertionHook())
9895 for (
auto *SelMI : Selects)
9896 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9900 if (NextMI.isDebugInstr()) {
9902 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9905 }
else if (User || ++
Count > 20)
9909 MachineInstr *LastMI = Selects.back();
9910 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9912 MachineBasicBlock *StartMBB =
MBB;
9942 for (
auto *SelMI : Selects)
9943 SelMI->eraseFromParent();
9946 for (
auto *DbgMI : DbgValues)
9947 MBB->
splice(InsertPos, StartMBB, DbgMI);
9958 unsigned StoreOpcode,
9959 unsigned STOCOpcode,
9960 bool Invert)
const {
9961 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
9964 MachineOperand
Base =
MI.getOperand(1);
9965 int64_t Disp =
MI.getOperand(2).getImm();
9966 Register IndexReg =
MI.getOperand(3).getReg();
9967 unsigned CCValid =
MI.getOperand(4).getImm();
9968 unsigned CCMask =
MI.getOperand(5).getImm();
9971 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
9975 MachineMemOperand *MMO =
nullptr;
9976 for (
auto *
I :
MI.memoperands())
9985 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
9997 MI.eraseFromParent();
10005 MachineBasicBlock *StartMBB =
MBB;
10011 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
10038 MI.eraseFromParent();
10048 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10056 MachineBasicBlock *StartMBB =
MBB;
10074 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
10093 Register Temp =
MRI.createVirtualRegister(&SystemZ::VR128BitRegClass);
10101 MI.eraseFromParent();
10112 bool Invert)
const {
10114 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10121 int64_t Disp =
MI.getOperand(2).getImm();
10123 Register BitShift =
MI.getOperand(4).getReg();
10124 Register NegBitShift =
MI.getOperand(5).getReg();
10125 unsigned BitSize =
MI.getOperand(6).getImm();
10129 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10130 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10131 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10134 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10135 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10136 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10137 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10138 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10141 MachineBasicBlock *StartMBB =
MBB;
10169 Register Tmp =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10174 }
else if (BinOpcode)
10197 MI.eraseFromParent();
10208 unsigned KeepOldMask)
const {
10210 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10216 int64_t Disp =
MI.getOperand(2).getImm();
10218 Register BitShift =
MI.getOperand(4).getReg();
10219 Register NegBitShift =
MI.getOperand(5).getReg();
10220 unsigned BitSize =
MI.getOperand(6).getImm();
10224 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10225 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10226 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10229 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10230 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10231 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10232 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10233 Register RotatedAltVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10234 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10237 MachineBasicBlock *StartMBB =
MBB;
10301 MI.eraseFromParent();
10311 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10317 int64_t Disp =
MI.getOperand(2).getImm();
10318 Register CmpVal =
MI.getOperand(3).getReg();
10319 Register OrigSwapVal =
MI.getOperand(4).getReg();
10320 Register BitShift =
MI.getOperand(5).getReg();
10321 Register NegBitShift =
MI.getOperand(6).getReg();
10322 int64_t BitSize =
MI.getOperand(7).getImm();
10325 const TargetRegisterClass *RC = &SystemZ::GR32BitRegClass;
10328 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10329 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10330 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10331 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10334 Register OrigOldVal =
MRI.createVirtualRegister(RC);
10336 Register SwapVal =
MRI.createVirtualRegister(RC);
10337 Register StoreVal =
MRI.createVirtualRegister(RC);
10338 Register OldValRot =
MRI.createVirtualRegister(RC);
10339 Register RetryOldVal =
MRI.createVirtualRegister(RC);
10340 Register RetrySwapVal =
MRI.createVirtualRegister(RC);
10343 MachineBasicBlock *StartMBB =
MBB;
10415 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10418 MI.eraseFromParent();
10426 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10431 .
add(
MI.getOperand(1))
10432 .
addImm(SystemZ::subreg_h64)
10433 .
add(
MI.getOperand(2))
10434 .
addImm(SystemZ::subreg_l64);
10435 MI.eraseFromParent();
10444 bool ClearEven)
const {
10446 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10452 Register In128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10456 Register NewIn128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10457 Register Zero64 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10468 MI.eraseFromParent();
10475 unsigned Opcode,
bool IsMemset)
const {
10477 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10482 uint64_t DestDisp =
MI.getOperand(1).getImm();
10487 auto foldDisplIfNeeded = [&](MachineOperand &
Base, uint64_t &Disp) ->
void {
10489 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10490 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10500 SrcDisp =
MI.getOperand(3).getImm();
10502 SrcBase = DestBase;
10503 SrcDisp = DestDisp++;
10504 foldDisplIfNeeded(DestBase, DestDisp);
10507 MachineOperand &LengthMO =
MI.getOperand(IsMemset ? 2 : 4);
10508 bool IsImmForm = LengthMO.
isImm();
10509 bool IsRegForm = !IsImmForm;
10512 auto insertMemMemOp = [&](MachineBasicBlock *InsMBB,
10514 MachineOperand DBase, uint64_t DDisp,
10515 MachineOperand
SBase, uint64_t SDisp,
10516 unsigned Length) ->
void {
10520 if (ByteMO.
isImm())
10535 bool NeedsLoop =
false;
10536 uint64_t ImmLength = 0;
10537 Register LenAdjReg = SystemZ::NoRegister;
10539 ImmLength = LengthMO.
getImm();
10540 ImmLength += IsMemset ? 2 : 1;
10541 if (ImmLength == 0) {
10542 MI.eraseFromParent();
10545 if (Opcode == SystemZ::CLC) {
10546 if (ImmLength > 3 * 256)
10556 }
else if (ImmLength > 6 * 256)
10564 LenAdjReg = LengthMO.
getReg();
10569 MachineBasicBlock *EndMBB =
10570 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10576 MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10578 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10588 auto loadZeroAddress = [&]() -> MachineOperand {
10589 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10593 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10594 DestBase = loadZeroAddress();
10595 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10596 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10598 MachineBasicBlock *StartMBB =
nullptr;
10599 MachineBasicBlock *LoopMBB =
nullptr;
10600 MachineBasicBlock *NextMBB =
nullptr;
10601 MachineBasicBlock *DoneMBB =
nullptr;
10602 MachineBasicBlock *AllDoneMBB =
nullptr;
10606 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10608 const TargetRegisterClass *RC = &SystemZ::ADDR64BitRegClass;
10609 Register ThisSrcReg =
MRI.createVirtualRegister(RC);
10611 (HaveSingleBase ? ThisSrcReg :
MRI.createVirtualRegister(RC));
10612 Register NextSrcReg =
MRI.createVirtualRegister(RC);
10614 (HaveSingleBase ? NextSrcReg :
MRI.createVirtualRegister(RC));
10615 RC = &SystemZ::GR64BitRegClass;
10616 Register ThisCountReg =
MRI.createVirtualRegister(RC);
10617 Register NextCountReg =
MRI.createVirtualRegister(RC);
10643 MBB = MemsetOneCheckMBB;
10654 MBB = MemsetOneMBB;
10686 if (EndMBB && !ImmLength)
10708 if (!HaveSingleBase)
10715 if (Opcode == SystemZ::MVC)
10742 if (!HaveSingleBase)
10764 Register RemSrcReg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10765 Register RemDestReg = HaveSingleBase ? RemSrcReg
10766 :
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10770 if (!HaveSingleBase)
10778 MachineInstrBuilder EXRL_MIB =
10786 if (Opcode != SystemZ::MVC) {
10796 while (ImmLength > 0) {
10797 uint64_t ThisLength = std::min(ImmLength, uint64_t(256));
10800 foldDisplIfNeeded(DestBase, DestDisp);
10801 foldDisplIfNeeded(SrcBase, SrcDisp);
10802 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10803 DestDisp += ThisLength;
10804 SrcDisp += ThisLength;
10805 ImmLength -= ThisLength;
10808 if (EndMBB && ImmLength > 0) {
10824 MI.eraseFromParent();
10833 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10837 uint64_t End1Reg =
MI.getOperand(0).getReg();
10838 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10839 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10840 uint64_t CharReg =
MI.getOperand(3).getReg();
10842 const TargetRegisterClass *RC = &SystemZ::GR64BitRegClass;
10843 uint64_t This1Reg =
MRI.createVirtualRegister(RC);
10844 uint64_t This2Reg =
MRI.createVirtualRegister(RC);
10845 uint64_t End2Reg =
MRI.createVirtualRegister(RC);
10847 MachineBasicBlock *StartMBB =
MBB;
10883 MI.eraseFromParent();
10890 bool NoFloat)
const {
10892 const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
10893 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10896 MI.setDesc(
TII->get(Opcode));
10900 uint64_t Control =
MI.getOperand(2).getImm();
10901 static const unsigned GPRControlBit[16] = {
10902 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10903 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10905 Control |= GPRControlBit[15];
10906 if (TFI->
hasFP(MF))
10907 Control |= GPRControlBit[11];
10908 MI.getOperand(2).setImm(Control);
10911 for (
int I = 0;
I < 16;
I++) {
10912 if ((Control & GPRControlBit[
I]) == 0) {
10919 if (!NoFloat && (Control & 4) != 0) {
10920 if (Subtarget.hasVector()) {
10938 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10941 Register SrcReg =
MI.getOperand(0).getReg();
10944 const TargetRegisterClass *RC =
MRI->getRegClass(SrcReg);
10945 Register DstReg =
MRI->createVirtualRegister(RC);
10952 MI.eraseFromParent();
10961 const SystemZInstrInfo *
TII = Subtarget.getInstrInfo();
10964 Register DstReg =
MI.getOperand(0).getReg();
10965 Register SizeReg =
MI.getOperand(2).getReg();
10967 MachineBasicBlock *StartMBB =
MBB;
10977 Register PHIReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10978 Register IncReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
11043 MI.eraseFromParent();
11047SDValue SystemZTargetLowering::
11050 auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
11058 switch (
MI.getOpcode()) {
11059 case SystemZ::ADJCALLSTACKDOWN:
11060 case SystemZ::ADJCALLSTACKUP:
11061 return emitAdjCallStack(
MI,
MBB);
11063 case SystemZ::Select32:
11064 case SystemZ::Select64:
11065 case SystemZ::Select128:
11066 case SystemZ::SelectF32:
11067 case SystemZ::SelectF64:
11068 case SystemZ::SelectF128:
11069 case SystemZ::SelectVR32:
11070 case SystemZ::SelectVR64:
11071 case SystemZ::SelectVR128:
11072 return emitSelect(
MI,
MBB);
11074 case SystemZ::CondStore8Mux:
11075 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
11076 case SystemZ::CondStore8MuxInv:
11077 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
11078 case SystemZ::CondStore16Mux:
11079 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
11080 case SystemZ::CondStore16MuxInv:
11081 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
11082 case SystemZ::CondStore32Mux:
11083 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
11084 case SystemZ::CondStore32MuxInv:
11085 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
11086 case SystemZ::CondStore8:
11087 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
11088 case SystemZ::CondStore8Inv:
11089 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
11090 case SystemZ::CondStore16:
11091 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
11092 case SystemZ::CondStore16Inv:
11093 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
11094 case SystemZ::CondStore32:
11095 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
11096 case SystemZ::CondStore32Inv:
11097 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
11098 case SystemZ::CondStore64:
11099 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
11100 case SystemZ::CondStore64Inv:
11101 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
11102 case SystemZ::CondStoreF32:
11103 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
11104 case SystemZ::CondStoreF32Inv:
11105 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
11106 case SystemZ::CondStoreF64:
11107 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
11108 case SystemZ::CondStoreF64Inv:
11109 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
11111 case SystemZ::SCmp128Hi:
11112 return emitICmp128Hi(
MI,
MBB,
false);
11113 case SystemZ::UCmp128Hi:
11114 return emitICmp128Hi(
MI,
MBB,
true);
11116 case SystemZ::PAIR128:
11117 return emitPair128(
MI,
MBB);
11118 case SystemZ::AEXT128:
11119 return emitExt128(
MI,
MBB,
false);
11120 case SystemZ::ZEXT128:
11121 return emitExt128(
MI,
MBB,
true);
11123 case SystemZ::ATOMIC_SWAPW:
11124 return emitAtomicLoadBinary(
MI,
MBB, 0);
11126 case SystemZ::ATOMIC_LOADW_AR:
11127 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
11128 case SystemZ::ATOMIC_LOADW_AFI:
11129 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
11131 case SystemZ::ATOMIC_LOADW_SR:
11132 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
11134 case SystemZ::ATOMIC_LOADW_NR:
11135 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
11136 case SystemZ::ATOMIC_LOADW_NILH:
11137 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
11139 case SystemZ::ATOMIC_LOADW_OR:
11140 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
11141 case SystemZ::ATOMIC_LOADW_OILH:
11142 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
11144 case SystemZ::ATOMIC_LOADW_XR:
11145 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
11146 case SystemZ::ATOMIC_LOADW_XILF:
11147 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
11149 case SystemZ::ATOMIC_LOADW_NRi:
11150 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
11151 case SystemZ::ATOMIC_LOADW_NILHi:
11152 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
11154 case SystemZ::ATOMIC_LOADW_MIN:
11156 case SystemZ::ATOMIC_LOADW_MAX:
11158 case SystemZ::ATOMIC_LOADW_UMIN:
11160 case SystemZ::ATOMIC_LOADW_UMAX:
11163 case SystemZ::ATOMIC_CMP_SWAPW:
11164 return emitAtomicCmpSwapW(
MI,
MBB);
11165 case SystemZ::MVCImm:
11166 case SystemZ::MVCReg:
11167 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
11168 case SystemZ::NCImm:
11169 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
11170 case SystemZ::OCImm:
11171 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
11172 case SystemZ::XCImm:
11173 case SystemZ::XCReg:
11174 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
11175 case SystemZ::CLCImm:
11176 case SystemZ::CLCReg:
11177 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
11178 case SystemZ::MemsetImmImm:
11179 case SystemZ::MemsetImmReg:
11180 case SystemZ::MemsetRegImm:
11181 case SystemZ::MemsetRegReg:
11182 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
11183 case SystemZ::CLSTLoop:
11184 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
11185 case SystemZ::MVSTLoop:
11186 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
11187 case SystemZ::SRSTLoop:
11188 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
11189 case SystemZ::TBEGIN:
11190 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
11191 case SystemZ::TBEGIN_nofloat:
11192 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
11193 case SystemZ::TBEGINC:
11194 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
11195 case SystemZ::LTEBRCompare_Pseudo:
11196 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
11197 case SystemZ::LTDBRCompare_Pseudo:
11198 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
11199 case SystemZ::LTXBRCompare_Pseudo:
11200 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
11202 case SystemZ::PROBED_ALLOCA:
11203 return emitProbedAlloca(
MI,
MBB);
11204 case SystemZ::EH_SjLj_SetJmp:
11206 case SystemZ::EH_SjLj_LongJmp:
11209 case TargetOpcode::STACKMAP:
11210 case TargetOpcode::PATCHPOINT:
11221SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11222 if (VT == MVT::Untyped)
11223 return &SystemZ::ADDR128BitRegClass;
11249 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11269 EVT VT =
Op.getValueType();
11270 Op =
Op.getOperand(0);
11271 EVT OpVT =
Op.getValueType();
11273 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11284 Op = DAG.
getNode(SystemZISD::VSUM,
DL, MVT::v4i32,
Op, Zero);
11304 const AttributeList &Attrs =
F->getAttributes();
11305 if (Attrs.hasRetAttrs())
11306 OS << Attrs.getAsString(AttributeList::ReturnIndex) <<
" ";
11307 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11308 for (
unsigned I = 0,
E = FT->getNumParams();
I !=
E; ++
I) {
11311 OS << *FT->getParamType(
I);
11313 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11320bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11321 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11322 if (Itr == IsInternalCache.end())
11323 Itr = IsInternalCache
11324 .insert(std::pair<const Function *, bool>(
11327 return Itr->second;
11330void SystemZTargetLowering::
11338 bool IsInternal =
false;
11339 const Function *CalleeFn =
nullptr;
11342 IsInternal = isInternal(CalleeFn);
11343 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11344 errs() <<
"ERROR: Missing extension attribute of passed "
11345 <<
"value in call to function:\n" <<
"Callee: ";
11346 if (CalleeFn !=
nullptr)
11350 errs() <<
"Caller: ";
11356void SystemZTargetLowering::
11364 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11365 errs() <<
"ERROR: Missing extension attribute of returned "
11366 <<
"value from function:\n";
11374bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11376 if (!Subtarget.isTargetELF())
11385 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11386 MVT VT = Outs[i].VT;
11387 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
11390 "Unexpected integer argument VT.");
11391 if (VT == MVT::i32 &&
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Register Bank Select
static bool isZeroVector(SDValue N)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
Function Alias Analysis Results
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static SDValue convertValVTToLocVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
static SDValue convertLocVTToValVT(SelectionDAG &DAG, SDValue Val, const CCValAssign &VA, const SDLoc &DL)
const HexagonInstrInfo * TII
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isSelectPseudo(MachineInstr &MI)
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
uint64_t IntrinsicInst * II
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the SmallSet class.
static SDValue getI128Select(SelectionDAG &DAG, const SDLoc &DL, Comparison C, SDValue TrueOp, SDValue FalseOp)
static SmallVector< SDValue, 4 > simplifyAssumingCCVal(SDValue &Val, SDValue &CC, SelectionDAG &DAG)
static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS)
static void adjustForLTGFR(Comparison &C)
static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0, SDValue Op1)
static cl::opt< bool > EnableIntArgExtCheck("argext-abi-check", cl::init(false), cl::desc("Verify that narrow int args are properly extended per the " "SystemZ ABI."))
static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG)
static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT, unsigned Opcode, SDValue Op0, SDValue Op1, SDValue &Even, SDValue &Odd)
static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)
static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Value)
static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In)
static bool isSimpleShift(SDValue N, unsigned &ShiftVal)
static 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 bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend, SDValue Op0, SDValue Op1, SDValue &Hi, SDValue &Lo)
static bool isF128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static void createPHIsForSelects(SmallVector< MachineInstr *, 8 > &Selects, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, MachineBasicBlock *SinkMBB)
static SDValue getGeneralPermuteNode(SelectionDAG &DAG, const SDLoc &DL, SDValue *Ops, const SmallVectorImpl< int > &Bytes)
static unsigned getVectorComparisonOrInvert(ISD::CondCode CC, CmpMode Mode, bool &Invert)
static unsigned CCMaskForCondCode(ISD::CondCode CC)
static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void adjustForFNeg(Comparison &C)
static bool isScalarToVector(SDValue Op)
static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue CCReg, unsigned CCValid, unsigned CCMask)
static bool matchPermute(const SmallVectorImpl< int > &Bytes, const Permute &P, unsigned &OpNo0, unsigned &OpNo1)
static bool isAddCarryChain(SDValue Carry)
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static MachineOperand earlyUseOperand(MachineOperand Op)
static bool canUseSiblingCall(const CCState &ArgCCInfo, SmallVectorImpl< CCValAssign > &ArgLocs, SmallVectorImpl< ISD::OutputArg > &Outs)
static bool getzOSCalleeAndADA(SelectionDAG &DAG, SDValue &Callee, SDValue &ADA, SDLoc &DL, SDValue &Chain)
static SDValue convertToF16(SDValue Op, SelectionDAG &DAG)
static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask, SelectionDAG &DAG)
static bool shouldSwapCmpOperands(const Comparison &C)
static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType)
static SDValue getADAEntry(SelectionDAG &DAG, SDValue Val, SDLoc DL, unsigned Offset, bool LoadAdr=false)
static SDNode * emitIntrinsicWithCC(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static void adjustForSubtraction(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool getVPermMask(SDValue ShuffleOp, SmallVectorImpl< int > &Bytes)
static const Permute PermuteForms[]
static std::pair< SDValue, int > findCCUse(const SDValue &Val)
static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static bool isSubBorrowChain(SDValue Carry)
static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool analyzeArgSplit(const SmallVectorImpl< ArgTy > &Args, SmallVector< CCValAssign, 16 > &ArgLocs, unsigned I, MVT &PartVT, unsigned &NumParts)
static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts, unsigned OpNo)
static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op, bool IsNegative)
static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static SDValue expandBitCastI128ToF128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static SDValue tryBuildVectorShuffle(SelectionDAG &DAG, BuildVectorSDNode *BVN)
static SDValue convertFromF16(SDValue Op, SDLoc DL, SelectionDAG &DAG)
static unsigned getVectorComparison(ISD::CondCode CC, CmpMode Mode)
static SDValue lowerGR128ToI128(SelectionDAG &DAG, SDValue In)
static SDValue MergeInputChains(SDNode *N1, SDNode *N2)
static SDValue expandBitCastF128ToI128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, uint64_t Mask, uint64_t CmpVal, unsigned ICmpType)
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL, SDValue Op, SDValue Chain)
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static bool checkCCKill(MachineInstr &MI, MachineBasicBlock *MBB)
static Register forceReg(MachineInstr &MI, MachineOperand &Base, const SystemZInstrInfo *TII)
static bool is32Bit(EVT VT)
static std::pair< unsigned, const TargetRegisterClass * > parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC, const unsigned *Map, unsigned Size)
static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, const SystemZSubtarget &Subtarget, SDValue &Op)
static bool matchDoublePermute(const SmallVectorImpl< int > &Bytes, const Permute &P, SmallVectorImpl< int > &Transform)
static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, SDValue Call, unsigned CCValid, uint64_t CC, ISD::CondCode Cond)
static SDValue buildFPVecFromScalars4(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SmallVectorImpl< SDValue > &Elems, unsigned Pos)
static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg)
static AddressingMode getLoadStoreAddrMode(bool HasVector, Type *Ty)
static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Op0, SDValue Op1)
static void computeKnownBitsBinOp(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static bool getShuffleInput(const SmallVectorImpl< int > &Bytes, unsigned Start, unsigned BytesPerElement, int &Base)
static AddressingMode supportedAddressingMode(Instruction *I, bool HasVector)
static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
static APInt getSignMask(unsigned BitWidth)
Get the SignMask for a specific bit width.
uint64_t getZExtValue() const
Get zero extended value.
void setBitsFrom(unsigned loBit)
Set the top bits starting from loBit.
unsigned getActiveBits() const
Compute the number of active bits in the value.
LLVM_ABI APInt trunc(unsigned width) const
Truncate to new width.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit)
Get a value with a block of bits set.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isSingleWord() const
Determine if this APInt just has one word to store value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
void lshrInPlace(unsigned ShiftAmt)
Logical right-shift this APInt by ShiftAmt in place.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
This class holds the attributes for a particular argument, parameter, function, or return value.
LLVM_ABI bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
LLVM Basic Block Representation.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI bool isConstant() const
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
const Constant * getConstVal() const
uint64_t getZExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false, bool IgnoreCastedDirectCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
static auto integer_fixedlen_vector_valuetypes()
uint64_t getScalarSizeInBits() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setMachineBlockAddressTaken()
Set this block to indicate that its address is used as something other than the target of a terminato...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setAdjustsStack(bool V)
void setFrameAddressIsTaken(bool T)
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setReturnAddressIsTaken(bool s)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void push_back(MachineBasicBlock *MBB)
reverse_iterator rbegin()
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
LLVM_ABI SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS)
Return an AddrSpaceCastSDNode.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getAtomicLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT MemVT, EVT VT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO)
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI bool isConstantIntBuildVectorOrConstantInt(SDValue N, bool AllowOpaques=true) const
Test whether the given value is a constant int or similar node.
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI std::pair< SDValue, SDValue > getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT)
Convert Op, which must be a STRICT operation of float type, to the float type VT, by either extending...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
ArrayRef< int > getMask() const
const_iterator begin() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A SystemZ-specific class detailing special use registers particular for calling conventions.
virtual int getStackPointerBias()=0
virtual int getReturnFunctionAddressRegister()=0
virtual int getCallFrameSize()=0
virtual int getStackPointerRegister()=0
static SystemZConstantPoolValue * Create(const GlobalValue *GV, SystemZCP::SystemZCPModifier Modifier)
unsigned getVarArgsFrameIndex() const
void setVarArgsFrameIndex(unsigned FI)
void setRegSaveFrameIndex(unsigned FI)
void incNumLocalDynamicTLSAccesses()
Register getVarArgsFirstGPR() const
void setADAVirtualRegister(Register Reg)
void setVarArgsFirstGPR(Register GPR)
Register getADAVirtualRegister() const
void setSizeOfFnParams(unsigned Size)
void setVarArgsFirstFPR(Register FPR)
unsigned getRegSaveFrameIndex() const
Register getVarArgsFirstFPR() const
const SystemZInstrInfo * getInstrInfo() const override
SystemZCallingConventionRegisters * getSpecialRegisters() const
AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
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
CondMergingParams getJumpConditionMergingParams(Instruction::BinaryOps Opc, const Value *Lhs, const Value *Rhs) const override
bool useSoftFloat() const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
std::pair< SDValue, SDValue > makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT, ArrayRef< SDValue > Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL, bool DoesNotReturn, bool IsReturnValueUsed) const
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain targets require unusual breakdowns of certain types.
SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI)
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, std::optional< CallingConv::ID > CC) const override
Target-specific combining of register parts into its original value.
bool isTruncateFree(Type *, Type *) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg, SDLoc DL, SDValue Chain, bool IsStrict) const
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine the number of bits in the operation that are sign bits.
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool isLegalAddImmediate(int64_t Imm) const override
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const override
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
bool isGuaranteedNotToBeUndefOrPoisonForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, bool PoisonOnly, unsigned Depth) const override
Return true if this function can prove that Op is never poison and, if PoisonOnly is false,...
AtomicExpansionKind shouldCastAtomicStoreInIR(StoreInst *SI) const override
Returns how the given (atomic) store should be cast by the IR-level AtomicExpand pass into.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool hasAndNot(SDValue Y) const override
Return true if the target has a bitwise and-not operation: X = ~A & B This can be used to simplify se...
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl< ISD::InputArg > &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower the incoming (formal) arguments, described by the Ins array,...
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
unsigned getStackProbeSize(const MachineFunction &MF) const
XPLINK64 calling convention specific use registers Particular to z/OS when in 64 bit mode.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
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...
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Let target indicate that an extending atomic load of the specified type is legal.
virtual unsigned getVectorTypeBreakdownForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT, unsigned &NumIntermediates, MVT &RegisterVT) const
Certain targets such as MIPS require that some types such as vectors are always broken down into scal...
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes, EVT *LargestVT=nullptr) const
Determines the optimal series of memory ops to replace the memset / memcpy.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
unsigned getPointerSize(unsigned AS) const
Get the pointer size for this target.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
bool hasOneUse() const
Return true if there is exactly one use of this value.
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
A raw_ostream that writes to a file descriptor.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ MEMBARRIER
MEMBARRIER - Compiler barrier only; generate a no-op.
@ ATOMIC_FENCE
OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope) This corresponds to the fence instruction.
@ SIGN_EXTEND_VECTOR_INREG
SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register sign-extension of the low ...
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ CTTZ_ZERO_UNDEF
Bit counting operators with an undefined result for zero inputs.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ VECREDUCE_ADD
Integer reductions may have a result type larger than the vector element type.
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ ANY_EXTEND_VECTOR_INREG
ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register any-extension of the low la...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FMINIMUM
FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0 as less than 0....
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ ZERO_EXTEND_VECTOR_INREG
ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an in-register zero-extension of the low ...
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
LLVM_ABI bool isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are 0 o...
LLVM_ABI CondCode getSetCCInverse(CondCode Operation, EVT Type)
Return the operation corresponding to !(X op Y), where 'op' is a valid SetCC operation.
LLVM_ABI CondCode getSetCCSwappedOperands(CondCode Operation)
Return the operation corresponding to (Y op X) when given the operation for (X op Y).
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
class_match< CmpInst > m_Cmp()
Matches any compare instruction and ignore it.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ System
Synchronized with respect to all concurrently executing threads.
@ MO_ADA_DATA_SYMBOL_ADDR
@ MO_ADA_DIRECT_FUNC_DESC
@ MO_ADA_INDIRECT_FUNC_DESC
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const int64_t ELFCallFrameSize
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned VR32Regs[32]
unsigned odd128(bool Is32bit)
const unsigned CCMASK_CMP_GE
static bool isImmHH(uint64_t Val)
const unsigned CCMASK_TEND
const unsigned CCMASK_CS_EQ
const unsigned CCMASK_TBEGIN
const MCPhysReg ELFArgFPRs[ELFNumArgFPRs]
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_TM_SOME_1
const unsigned CCMASK_LOGICAL_CARRY
const unsigned TDCMASK_NORMAL_MINUS
const unsigned CCMASK_TDC
const unsigned CCMASK_FCMP
const unsigned CCMASK_TM_SOME_0
static bool isImmHL(uint64_t Val)
const unsigned TDCMASK_SUBNORMAL_MINUS
const unsigned TDCMASK_NORMAL_PLUS
const unsigned CCMASK_CMP_GT
const unsigned TDCMASK_QNAN_MINUS
const unsigned CCMASK_ANY
const unsigned CCMASK_ARITH
const unsigned CCMASK_TM_MIXED_MSB_0
const unsigned TDCMASK_SUBNORMAL_PLUS
static bool isImmLL(uint64_t Val)
const unsigned VectorBits
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned TDCMASK_INFINITY_PLUS
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_TM_ALL_0
const unsigned CCMASK_CMP_LE
const unsigned CCMASK_CMP_O
const unsigned CCMASK_CMP_EQ
const unsigned VectorBytes
const unsigned TDCMASK_INFINITY_MINUS
const unsigned CCMASK_ICMP
const unsigned CCMASK_VCMP_ALL
const unsigned CCMASK_VCMP_NONE
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_VCMP
const unsigned CCMASK_TM_MIXED_MSB_1
const unsigned CCMASK_TM_MSB_0
const unsigned CCMASK_ARITH_OVERFLOW
const unsigned CCMASK_CS_NE
const unsigned TDCMASK_SNAN_PLUS
const unsigned CCMASK_NONE
const unsigned CCMASK_CMP_LT
const unsigned CCMASK_CMP_NE
const unsigned TDCMASK_ZERO_PLUS
const unsigned TDCMASK_QNAN_PLUS
const unsigned TDCMASK_ZERO_MINUS
unsigned even128(bool Is32bit)
const unsigned CCMASK_TM_ALL_1
const unsigned CCMASK_LOGICAL_BORROW
const unsigned ELFNumArgFPRs
const unsigned CCMASK_CMP_UO
const unsigned CCMASK_LOGICAL
const unsigned CCMASK_TM_MSB_1
const unsigned TDCMASK_SNAN_MINUS
initializer< Ty > init(const Ty &Val)
support::ulittle32_t Word
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
FunctionAddr VTableAddr Value
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ 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.
testing::Matcher< const detail::ErrorHolder & > Failed()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
LLVM_ABI void dumpBytes(ArrayRef< uint8_t > Bytes, raw_ostream &OS)
Convert ‘Bytes’ to a hex string and output to ‘OS’.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
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...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
AddressingMode(bool LongDispl, bool IdxReg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
KnownBits anyextOrTrunc(unsigned BitWidth) const
Return known bits for an "any" extension or truncation of the value we're tracking.
unsigned getBitWidth() const
Get the bit width of this value.
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
void resetAll()
Resets the known state of all bits.
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
KnownBits sext(unsigned BitWidth) const
Return known bits for a sign extension of the value we're tracking.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
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.