26#include "llvm/IR/IntrinsicsS390.h"
35#define DEBUG_TYPE "systemz-lower"
41 cl::desc(
"Verify that narrow int args are properly extended per the "
48 : Op0(Op0In), Op1(Op1In), Chain(ChainIn),
49 Opcode(0), ICmpType(0), CCValid(0), CCMask(0) {}
99 if (Subtarget.hasHighWord())
105 if (Subtarget.hasVector()) {
114 if (Subtarget.hasVectorEnhancements1())
119 if (Subtarget.hasVector()) {
128 if (Subtarget.hasVector())
155 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
156 I <= MVT::LAST_FP_VALUETYPE;
182 for (
unsigned I = MVT::FIRST_INTEGER_VALUETYPE;
183 I <= MVT::LAST_INTEGER_VALUETYPE;
214 if (Subtarget.hasPopulationCount())
240 (!Subtarget.hasFPExtension() && VT == MVT::i32) ?
Promote :
Custom;
261 if (!Subtarget.hasVectorEnhancements3()) {
288 if (Subtarget.hasVectorEnhancements3()) {
331 {MVT::i8, MVT::i16, MVT::i32},
Legal);
333 {MVT::i8, MVT::i16},
Legal);
354 if (Subtarget.hasMiscellaneousExtensions4()) {
361 if (Subtarget.hasMiscellaneousExtensions3()) {
454 if (VT != MVT::v2i64 || Subtarget.hasVectorEnhancements3()) {
459 if (Subtarget.hasVectorEnhancements3() &&
460 VT != MVT::v16i8 && VT != MVT::v8i16) {
470 if (Subtarget.hasVectorEnhancements1())
504 if (Subtarget.hasVector()) {
526 if (Subtarget.hasVectorEnhancements2()) {
552 for (
MVT VT : {MVT::f32, MVT::f64, MVT::f128}) {
566 for (
unsigned I = MVT::FIRST_FP_VALUETYPE;
567 I <= MVT::LAST_FP_VALUETYPE;
575 if (Subtarget.hasFPExtension()) {
603 if (Subtarget.hasFPExtension()) {
619 if (Subtarget.hasVector()) {
667 if (Subtarget.hasVectorEnhancements1()) {
674 if (Subtarget.hasVectorEnhancements1()) {
730 for (
auto VT : { MVT::f32, MVT::f64, MVT::f128,
731 MVT::v4f32, MVT::v2f64 }) {
740 if (!Subtarget.hasVectorEnhancements1()) {
746 if (Subtarget.hasVectorEnhancements1())
756 if (Subtarget.hasVectorEnhancements1()) {
768 if (!Subtarget.hasVector()) {
840 return Subtarget.hasSoftFloat();
865 return Subtarget.hasVectorEnhancements1();
878 if (!Subtarget.hasVector() ||
879 (isFP128 && !Subtarget.hasVectorEnhancements1()))
901 if (SplatBitSize > 64)
907 if (isInt<16>(SignedValue)) {
916 if (
TII->isRxSBGMask(
Value, SplatBitSize, Start,
End)) {
938 uint64_t Lower = SplatUndefZ & maskTrailingOnes<uint64_t>(LowerBits);
939 uint64_t Upper = SplatUndefZ & maskLeadingOnes<uint64_t>(UpperBits);
946 uint64_t Middle = SplatUndefZ & ~Upper & ~Lower;
947 return TryValue(SplatBitsZ | Middle);
962 unsigned HalfSize = Width / 2;
967 if (HighValue != LowValue || 8 > HalfSize)
970 SplatBits = HighValue;
974 SplatBitSize = Width;
982 BVN->
isConstantSplat(IntBits, SplatUndef, SplatBitSize, HasAnyUndefs, 128,
986 BVN->
isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs, 8,
991 bool ForCodeSize)
const {
993 if (Imm.isZero() || Imm.isNegZero())
1014 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
1016 Register MainDstReg =
MRI.createVirtualRegister(RC);
1017 Register RestoreDstReg =
MRI.createVirtualRegister(RC);
1020 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1073 const int64_t FPOffset = 0;
1082 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
1098 .
addReg(SpecialRegs->getFramePointerRegister())
1106 .
addReg(SpecialRegs->getStackPointerRegister())
1114 Register BCReg =
MRI.createVirtualRegister(PtrRC);
1117 .
addReg(SpecialRegs->getStackPointerRegister())
1118 .
addImm(TFL->getBackchainOffset(*MF))
1129 MIB =
BuildMI(*ThisMBB,
MI,
DL,
TII->get(SystemZ::EH_SjLj_Setup))
1154 MI.eraseFromParent();
1170 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
"Invalid Pointer Size!");
1180 const int64_t FPOffset = 0;
1192 SpecialRegs->getFramePointerRegister())
1214 SpecialRegs->getStackPointerRegister())
1223 .
addReg(SpecialRegs->getStackPointerRegister())
1224 .
addImm(TFL->getBackchainOffset(*MF))
1230 MI.eraseFromParent();
1260 if (Subtarget.hasInterlockedAccess1() &&
1274 return isInt<32>(Imm) || isUInt<32>(Imm);
1279 return isUInt<32>(Imm) || isUInt<32>(-Imm);
1293 EVT VT =
Y.getValueType();
1296 if (VT == MVT::i32 || VT == MVT::i64)
1297 return Subtarget.hasMiscellaneousExtensions3();
1300 if (VT.
isVector() || VT == MVT::i128)
1301 return Subtarget.hasVector();
1315 LongDisplacement(LongDispl), IndexReg(IdxReg) {}
1338 switch (
II->getIntrinsicID()) {
1340 case Intrinsic::memset:
1341 case Intrinsic::memmove:
1342 case Intrinsic::memcpy:
1347 if (isa<LoadInst>(
I) &&
I->hasOneUse()) {
1348 auto *SingleUser = cast<Instruction>(*
I->user_begin());
1349 if (SingleUser->getParent() ==
I->getParent()) {
1350 if (isa<ICmpInst>(SingleUser)) {
1351 if (
auto *
C = dyn_cast<ConstantInt>(SingleUser->getOperand(1)))
1352 if (
C->getBitWidth() <= 64 &&
1353 (isInt<16>(
C->getSExtValue()) || isUInt<16>(
C->getZExtValue())))
1356 }
else if (isa<StoreInst>(SingleUser))
1360 }
else if (
auto *StoreI = dyn_cast<StoreInst>(
I)) {
1361 if (
auto *LoadI = dyn_cast<LoadInst>(StoreI->getValueOperand()))
1362 if (LoadI->hasOneUse() && LoadI->getParent() ==
I->getParent())
1367 if (HasVector && (isa<LoadInst>(
I) || isa<StoreInst>(
I))) {
1375 Type *MemAccessTy = (isa<LoadInst>(
I) ?
I->getType() :
1376 I->getOperand(0)->getType());
1378 bool IsVectorAccess = MemAccessTy->
isVectorTy();
1382 if (!IsVectorAccess && isa<StoreInst>(
I)) {
1383 Value *DataOp =
I->getOperand(0);
1384 if (isa<ExtractElementInst>(DataOp))
1385 IsVectorAccess =
true;
1390 if (!IsVectorAccess && isa<LoadInst>(
I) &&
I->hasOneUse()) {
1391 User *LoadUser = *
I->user_begin();
1392 if (isa<InsertElementInst>(LoadUser))
1393 IsVectorAccess =
true;
1396 if (IsFPAccess || IsVectorAccess)
1425 return AM.
Scale == 0;
1432 LLVMContext &Context, std::vector<EVT> &MemOps,
unsigned Limit,
1433 const MemOp &
Op,
unsigned DstAS,
unsigned SrcAS,
1435 const int MVCFastLen = 16;
1437 if (Limit != ~
unsigned(0)) {
1439 if (
Op.isMemcpy() &&
Op.allowOverlap() &&
Op.size() <= MVCFastLen)
1441 if (
Op.isMemset() &&
Op.size() - 1 <= MVCFastLen)
1443 if (
Op.isZeroMemset())
1448 DstAS, SrcAS, FuncAttributes);
1454 return Subtarget.hasVector() ? MVT::v2i64 : MVT::Other;
1458 if (!FromType->isIntegerTy() || !ToType->
isIntegerTy())
1460 unsigned FromBits = FromType->getPrimitiveSizeInBits().getFixedValue();
1462 return FromBits > ToBits;
1470 return FromBits > ToBits;
1479 if (Constraint.
size() == 1) {
1480 switch (Constraint[0]) {
1506 }
else if (Constraint.
size() == 2 && Constraint[0] ==
'Z') {
1507 switch (Constraint[1]) {
1525 Value *CallOperandVal =
Info.CallOperandVal;
1528 if (!CallOperandVal)
1532 switch (*Constraint) {
1551 if (Subtarget.hasVector())
1557 if (
auto *
C = dyn_cast<ConstantInt>(CallOperandVal))
1558 if (isUInt<8>(
C->getZExtValue()))
1563 if (
auto *
C = dyn_cast<ConstantInt>(CallOperandVal))
1564 if (isUInt<12>(
C->getZExtValue()))
1569 if (
auto *
C = dyn_cast<ConstantInt>(CallOperandVal))
1570 if (isInt<16>(
C->getSExtValue()))
1575 if (
auto *
C = dyn_cast<ConstantInt>(CallOperandVal))
1576 if (isInt<20>(
C->getSExtValue()))
1581 if (
auto *
C = dyn_cast<ConstantInt>(CallOperandVal))
1582 if (
C->getZExtValue() == 0x7fffffff)
1592static std::pair<unsigned, const TargetRegisterClass *>
1594 const unsigned *Map,
unsigned Size) {
1595 assert(*(Constraint.
end()-1) ==
'}' &&
"Missing '}'");
1596 if (isdigit(Constraint[2])) {
1601 return std::make_pair(Map[Index], RC);
1603 return std::make_pair(0U,
nullptr);
1606std::pair<unsigned, const TargetRegisterClass *>
1609 if (Constraint.
size() == 1) {
1611 switch (Constraint[0]) {
1616 return std::make_pair(0U, &SystemZ::GR64BitRegClass);
1618 return std::make_pair(0U, &SystemZ::GR128BitRegClass);
1619 return std::make_pair(0U, &SystemZ::GR32BitRegClass);
1623 return std::make_pair(0U, &SystemZ::ADDR64BitRegClass);
1624 else if (VT == MVT::i128)
1625 return std::make_pair(0U, &SystemZ::ADDR128BitRegClass);
1626 return std::make_pair(0U, &SystemZ::ADDR32BitRegClass);
1629 return std::make_pair(0U, &SystemZ::GRH32BitRegClass);
1634 return std::make_pair(0U, &SystemZ::FP16BitRegClass);
1636 return std::make_pair(0U, &SystemZ::FP64BitRegClass);
1638 return std::make_pair(0U, &SystemZ::FP128BitRegClass);
1639 return std::make_pair(0U, &SystemZ::FP32BitRegClass);
1644 if (Subtarget.hasVector()) {
1646 return std::make_pair(0U, &SystemZ::VR16BitRegClass);
1648 return std::make_pair(0U, &SystemZ::VR32BitRegClass);
1650 return std::make_pair(0U, &SystemZ::VR64BitRegClass);
1651 return std::make_pair(0U, &SystemZ::VR128BitRegClass);
1660 auto getVTSizeInBits = [&VT]() {
1668 if (Constraint[1] ==
'r') {
1669 if (getVTSizeInBits() == 32)
1672 if (getVTSizeInBits() == 128)
1678 if (Constraint[1] ==
'f') {
1680 return std::make_pair(
1682 if (getVTSizeInBits() == 16)
1685 if (getVTSizeInBits() == 32)
1688 if (getVTSizeInBits() == 128)
1694 if (Constraint[1] ==
'v') {
1695 if (!Subtarget.hasVector())
1696 return std::make_pair(
1698 if (getVTSizeInBits() == 16)
1701 if (getVTSizeInBits() == 32)
1704 if (getVTSizeInBits() == 64)
1722 : SystemZ::NoRegister)
1724 Subtarget.
isTargetELF() ? SystemZ::R15D : SystemZ::NoRegister)
1731 const Constant *PersonalityFn)
const {
1736 const Constant *PersonalityFn)
const {
1744 if (Constraint.
size() == 1) {
1745 switch (Constraint[0]) {
1747 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op))
1748 if (isUInt<8>(
C->getZExtValue()))
1750 Op.getValueType()));
1754 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op))
1755 if (isUInt<12>(
C->getZExtValue()))
1757 Op.getValueType()));
1761 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op))
1762 if (isInt<16>(
C->getSExtValue()))
1764 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1768 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op))
1769 if (isInt<20>(
C->getSExtValue()))
1771 C->getSExtValue(),
SDLoc(
Op),
Op.getValueType()));
1775 if (
auto *
C = dyn_cast<ConstantSDNode>(
Op))
1776 if (
C->getZExtValue() == 0x7fffffff)
1778 Op.getValueType()));
1789#include "SystemZGenCallingConv.inc"
1793 static const MCPhysReg ScratchRegs[] = { SystemZ::R0D, SystemZ::R1D,
1799 Type *ToType)
const {
1862 if (BitCastToType == MVT::v2i64)
1889 MVT::Untyped,
Hi,
Lo);
1913 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
1915 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1926 MVT PartVT,
EVT ValueVT, std::optional<CallingConv::ID> CC)
const {
1927 if (ValueVT.
getSizeInBits() == 128 && NumParts == 1 && PartVT == MVT::Untyped) {
1954 unsigned NumFixedGPRs = 0;
1955 unsigned NumFixedFPRs = 0;
1956 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
1969 RC = &SystemZ::GR32BitRegClass;
1973 RC = &SystemZ::GR64BitRegClass;
1977 RC = &SystemZ::FP16BitRegClass;
1981 RC = &SystemZ::FP32BitRegClass;
1985 RC = &SystemZ::FP64BitRegClass;
1989 RC = &SystemZ::FP128BitRegClass;
1997 RC = &SystemZ::VR128BitRegClass;
2025 unsigned SlotOffs = VA.
getLocVT() == MVT::f16 ? 6 : 4;
2029 ArgValue = DAG.
getLoad(LocVT,
DL, Chain, FIN,
2040 unsigned ArgIndex = Ins[
I].OrigArgIndex;
2041 assert (Ins[
I].PartOffset == 0);
2042 while (
I + 1 != E && Ins[
I + 1].OrigArgIndex == ArgIndex) {
2044 unsigned PartOffset = Ins[
I + 1].PartOffset;
2067 int64_t VarArgOffset = CCInfo.
getStackSize() + Regs->getCallFrameSize();
2085 int64_t RegSaveOffset =
2100 &SystemZ::FP64BitRegClass);
2118 MRI.addLiveIn(Regs->getADARegister(), ADAvReg);
2130 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2137 if (Reg == SystemZ::R6H || Reg == SystemZ::R6L || Reg == SystemZ::R6D)
2139 if (Outs[
I].Flags.isSwiftSelf() || Outs[
I].Flags.isSwiftError())
2146 unsigned Offset,
bool LoadAdr =
false) {
2169 bool LoadAddr =
false;
2170 const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV);
2191 unsigned ADADelta = 0;
2192 unsigned EPADelta = 8;
2197 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2198 bool IsInternal = (
G->getGlobal()->hasInternalLinkage() ||
2199 G->getGlobal()->hasPrivateLinkage());
2214 }
else if (
auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2256 verifyNarrowIntegerArgs_Call(Outs, &MF.
getFunction(), Callee);
2260 CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, Ctx);
2279 for (
unsigned I = 0, E = ArgLocs.
size();
I != E; ++
I) {
2285 unsigned ArgIndex = Outs[
I].OrigArgIndex;
2287 if (
I + 1 != E && Outs[
I + 1].OrigArgIndex == ArgIndex) {
2289 Type *OrigArgType = CLI.
Args[Outs[
I].OrigArgIndex].Ty;
2295 SlotVT = Outs[
I].VT;
2298 int FI = cast<FrameIndexSDNode>(SpillSlot)->getIndex();
2304 assert (Outs[
I].PartOffset == 0);
2305 while (
I + 1 != E && Outs[
I + 1].OrigArgIndex == ArgIndex) {
2306 SDValue PartValue = OutVals[
I + 1];
2307 unsigned PartOffset = Outs[
I + 1].PartOffset;
2314 SlotVT.
getStoreSize()) &&
"Not enough space for argument part!");
2317 ArgValue = SpillSlot;
2334 if (!StackPtr.getNode())
2341 else if (VA.
getLocVT() == MVT::f16)
2358 RegsToPass.
push_back(std::make_pair(SystemZ::R3D, ShadowArgValue));
2364 if (!MemOpChains.
empty())
2377 ->getAddressOfCalleeRegister();
2380 Callee = DAG.
getRegister(CalleeReg, Callee.getValueType());
2385 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(Callee)) {
2388 }
else if (
auto *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
2391 }
else if (IsTailCall) {
2394 Callee = DAG.
getRegister(SystemZ::R1D, Callee.getValueType());
2399 for (
const auto &[Reg,
N] : RegsToPass) {
2411 for (
const auto &[Reg,
N] : RegsToPass)
2416 const uint32_t *Mask =
TRI->getCallPreservedMask(MF, CallConv);
2417 assert(Mask &&
"Missing call preserved mask for calling convention");
2441 CCState RetCCInfo(CallConv, IsVarArg, MF, RetLocs, Ctx);
2448 VA.getLocVT(), Glue);
2465 bool DoesNotReturn,
bool IsReturnValueUsed)
const {
2467 Args.reserve(Ops.
size());
2473 Entry.IsZExt = !Entry.IsSExt;
2474 Args.push_back(Entry);
2499 for (
auto &Out : Outs)
2500 if (Out.ArgVT == MVT::i128)
2505 return RetCCInfo.
CheckReturn(Outs, RetCC_SystemZ);
2517 verifyNarrowIntegerArgs_Ret(Outs, &MF.
getFunction());
2525 if (RetLocs.
empty())
2535 for (
unsigned I = 0, E = RetLocs.
size();
I != E; ++
I) {
2564 unsigned &CCValid) {
2565 unsigned Id =
Op.getConstantOperandVal(1);
2567 case Intrinsic::s390_tbegin:
2572 case Intrinsic::s390_tbegin_nofloat:
2577 case Intrinsic::s390_tend:
2591 unsigned Id =
Op.getConstantOperandVal(0);
2593 case Intrinsic::s390_vpkshs:
2594 case Intrinsic::s390_vpksfs:
2595 case Intrinsic::s390_vpksgs:
2600 case Intrinsic::s390_vpklshs:
2601 case Intrinsic::s390_vpklsfs:
2602 case Intrinsic::s390_vpklsgs:
2607 case Intrinsic::s390_vceqbs:
2608 case Intrinsic::s390_vceqhs:
2609 case Intrinsic::s390_vceqfs:
2610 case Intrinsic::s390_vceqgs:
2611 case Intrinsic::s390_vceqqs:
2616 case Intrinsic::s390_vchbs:
2617 case Intrinsic::s390_vchhs:
2618 case Intrinsic::s390_vchfs:
2619 case Intrinsic::s390_vchgs:
2620 case Intrinsic::s390_vchqs:
2625 case Intrinsic::s390_vchlbs:
2626 case Intrinsic::s390_vchlhs:
2627 case Intrinsic::s390_vchlfs:
2628 case Intrinsic::s390_vchlgs:
2629 case Intrinsic::s390_vchlqs:
2634 case Intrinsic::s390_vtm:
2639 case Intrinsic::s390_vfaebs:
2640 case Intrinsic::s390_vfaehs:
2641 case Intrinsic::s390_vfaefs:
2646 case Intrinsic::s390_vfaezbs:
2647 case Intrinsic::s390_vfaezhs:
2648 case Intrinsic::s390_vfaezfs:
2653 case Intrinsic::s390_vfeebs:
2654 case Intrinsic::s390_vfeehs:
2655 case Intrinsic::s390_vfeefs:
2660 case Intrinsic::s390_vfeezbs:
2661 case Intrinsic::s390_vfeezhs:
2662 case Intrinsic::s390_vfeezfs:
2667 case Intrinsic::s390_vfenebs:
2668 case Intrinsic::s390_vfenehs:
2669 case Intrinsic::s390_vfenefs:
2674 case Intrinsic::s390_vfenezbs:
2675 case Intrinsic::s390_vfenezhs:
2676 case Intrinsic::s390_vfenezfs:
2681 case Intrinsic::s390_vistrbs:
2682 case Intrinsic::s390_vistrhs:
2683 case Intrinsic::s390_vistrfs:
2688 case Intrinsic::s390_vstrcbs:
2689 case Intrinsic::s390_vstrchs:
2690 case Intrinsic::s390_vstrcfs:
2695 case Intrinsic::s390_vstrczbs:
2696 case Intrinsic::s390_vstrczhs:
2697 case Intrinsic::s390_vstrczfs:
2702 case Intrinsic::s390_vstrsb:
2703 case Intrinsic::s390_vstrsh:
2704 case Intrinsic::s390_vstrsf:
2709 case Intrinsic::s390_vstrszb:
2710 case Intrinsic::s390_vstrszh:
2711 case Intrinsic::s390_vstrszf:
2716 case Intrinsic::s390_vfcedbs:
2717 case Intrinsic::s390_vfcesbs:
2722 case Intrinsic::s390_vfchdbs:
2723 case Intrinsic::s390_vfchsbs:
2728 case Intrinsic::s390_vfchedbs:
2729 case Intrinsic::s390_vfchesbs:
2734 case Intrinsic::s390_vftcidb:
2735 case Intrinsic::s390_vftcisb:
2740 case Intrinsic::s390_tdc:
2758 for (
unsigned I = 2;
I < NumOps; ++
I)
2761 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
2767 return Intr.getNode();
2778 for (
unsigned I = 1;
I < NumOps; ++
I) {
2781 assert((
Op.getConstantOperandVal(0) == Intrinsic::s390_tdc &&
I == 1) &&
2782 "Unhandled intrinsic with f16 operand.");
2789 return Intr.getNode();
2799 case ISD::SET##X: return SystemZ::CCMASK_CMP_##X; \
2800 case ISD::SETO##X: return SystemZ::CCMASK_CMP_##X; \
2801 case ISD::SETU##X: return SystemZ::CCMASK_CMP_UO | SystemZ::CCMASK_CMP_##X
2826 auto *ConstOp1 = dyn_cast<ConstantSDNode>(
C.Op1.getNode());
2827 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2830 int64_t
Value = ConstOp1->getSExtValue();
2846 if (!
C.Op0.hasOneUse() ||
2852 auto *Load = cast<LoadSDNode>(
C.Op0);
2853 unsigned NumBits = Load->getMemoryVT().getSizeInBits();
2854 if ((NumBits != 8 && NumBits != 16) ||
2855 NumBits != Load->getMemoryVT().getStoreSizeInBits())
2860 auto *ConstOp1 = cast<ConstantSDNode>(
C.Op1);
2861 if (!ConstOp1 || ConstOp1->getValueSizeInBits(0) > 64)
2864 uint64_t Mask = (1 << NumBits) - 1;
2867 int64_t SignedValue = ConstOp1->getSExtValue();
2874 }
else if (NumBits == 8) {
2900 if (
C.Op0.getValueType() != MVT::i32 ||
2901 Load->getExtensionType() != ExtType) {
2903 Load->getBasePtr(), Load->getPointerInfo(),
2904 Load->getMemoryVT(), Load->getAlign(),
2905 Load->getMemOperand()->getFlags());
2911 if (
C.Op1.getValueType() != MVT::i32 ||
2912 Value != ConstOp1->getZExtValue())
2919 auto *Load = dyn_cast<LoadSDNode>(
Op.getNode());
2922 if (Load->getMemoryVT() == MVT::i8)
2925 switch (Load->getExtensionType()) {
2942 if (
C.Op0.getValueType() == MVT::i128)
2944 if (
C.Op0.getValueType() == MVT::f128)
2950 if (isa<ConstantFPSDNode>(
C.Op1))
2955 auto *ConstOp1 = dyn_cast<ConstantSDNode>(
C.Op1);
2956 if (ConstOp1 && ConstOp1->getZExtValue() == 0)
2974 isUInt<16>(ConstOp1->getZExtValue()))
2979 isInt<16>(ConstOp1->getSExtValue()))
2985 unsigned Opcode0 =
C.Op0.getOpcode();
2992 C.Op0.getConstantOperandVal(1) == 0xffffffff)
3007 ((
N->getOperand(0) ==
C.Op0 &&
N->getOperand(1) ==
C.Op1) ||
3008 (
N->getOperand(0) ==
C.Op1 &&
N->getOperand(1) ==
C.Op0))) {
3029 auto *C1 = dyn_cast<ConstantFPSDNode>(
C.Op1);
3030 if (C1 && C1->isZero()) {
3049 if (
C.Op0.getOpcode() ==
ISD::SHL &&
C.Op0.getValueType() == MVT::i64 &&
3051 auto *C1 = dyn_cast<ConstantSDNode>(
C.Op0.getOperand(1));
3052 if (C1 && C1->getZExtValue() == 32) {
3053 SDValue ShlOp0 =
C.Op0.getOperand(0);
3057 cast<VTSDNode>(
N->getOperand(1))->getVT() == MVT::i32) {
3072 C.Op0.getOperand(0).getOpcode() ==
ISD::LOAD &&
3074 cast<ConstantSDNode>(
C.Op1)->getValueSizeInBits(0) <= 64 &&
3075 C.Op1->getAsZExtVal() == 0) {
3076 auto *L = cast<LoadSDNode>(
C.Op0.getOperand(0));
3077 if (L->getMemoryVT().getStoreSizeInBits().getFixedValue() <=
3078 C.Op0.getValueSizeInBits().getFixedValue()) {
3079 unsigned Type = L->getExtensionType();
3082 C.Op0 =
C.Op0.getOperand(0);
3092 auto *Shift = dyn_cast<ConstantSDNode>(
N.getOperand(1));
3096 uint64_t Amount = Shift->getZExtValue();
3097 if (Amount >=
N.getValueSizeInBits())
3112 unsigned ICmpType) {
3113 assert(Mask != 0 &&
"ANDs with zero should have been removed by now");
3135 if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <=
Low) {
3141 if (EffectivelyUnsigned && CmpVal <
Low) {
3149 if (CmpVal == Mask) {
3155 if (EffectivelyUnsigned && CmpVal >= Mask -
Low && CmpVal < Mask) {
3161 if (EffectivelyUnsigned && CmpVal > Mask -
Low && CmpVal <= Mask) {
3169 if (EffectivelyUnsigned && CmpVal >= Mask -
High && CmpVal <
High) {
3175 if (EffectivelyUnsigned && CmpVal > Mask -
High && CmpVal <=
High) {
3204 if (
C.Op0.getValueType() == MVT::i128) {
3209 auto *Mask = dyn_cast<ConstantSDNode>(
C.Op1);
3210 if (Mask && Mask->getAPIntValue() == 0) {
3225 auto *ConstOp1 = dyn_cast<ConstantSDNode>(
C.Op1);
3228 uint64_t CmpVal = ConstOp1->getZExtValue();
3235 NewC.Op0 =
C.Op0.getOperand(0);
3236 NewC.Op1 =
C.Op0.getOperand(1);
3237 Mask = dyn_cast<ConstantSDNode>(NewC.Op1);
3240 MaskVal = Mask->getZExtValue();
3245 if (NewC.Op0.getValueType() != MVT::i64 ||
3260 MaskVal = -(CmpVal & -CmpVal);
3268 unsigned BitSize = NewC.Op0.getValueSizeInBits();
3269 unsigned NewCCMask, ShiftVal;
3271 NewC.Op0.getOpcode() ==
ISD::SHL &&
3273 (MaskVal >> ShiftVal != 0) &&
3274 ((CmpVal >> ShiftVal) << ShiftVal) == CmpVal &&
3276 MaskVal >> ShiftVal,
3279 NewC.Op0 = NewC.Op0.getOperand(0);
3280 MaskVal >>= ShiftVal;
3282 NewC.Op0.getOpcode() ==
ISD::SRL &&
3284 (MaskVal << ShiftVal != 0) &&
3285 ((CmpVal << ShiftVal) >> ShiftVal) == CmpVal &&
3287 MaskVal << ShiftVal,
3290 NewC.Op0 = NewC.Op0.getOperand(0);
3291 MaskVal <<= ShiftVal;
3302 if (Mask && Mask->getZExtValue() == MaskVal)
3307 C.CCMask = NewCCMask;
3315 if (
C.Op0.getValueType() != MVT::i128)
3326 Src = Src.getOperand(0);
3329 unsigned Opcode = 0;
3330 if (Src.hasOneUse()) {
3331 switch (Src.getOpcode()) {
3343 C.Op0 = Src->getOperand(0);
3344 C.Op1 = Src->getOperand(1);
3348 C.CCMask ^=
C.CCValid;
3372 bool Swap =
false, Invert =
false;
3391 C.CCMask ^=
C.CCValid;
3401 auto *Mask = dyn_cast<ConstantSDNode>(
C.Op0.getOperand(1));
3402 if (!Mask || Mask->getValueSizeInBits(0) > 64)
3405 if ((~Known.
Zero).getZExtValue() & ~Mask->getZExtValue())
3408 C.Op0 =
C.Op0.getOperand(0);
3420 C.CCValid = CCValid;
3423 C.CCMask = CC < 4 ? 1 << (3 - CC) : 0;
3426 C.CCMask = CC < 4 ? ~(1 << (3 - CC)) : -1;
3430 C.CCMask = CC < 4 ? ~0U << (4 - CC) : -1;
3433 C.CCMask = CC < 4 ? ~(~0U << (4 - CC)) : 0;
3437 C.CCMask = CC < 4 ? ~0U << (3 - CC) : -1;
3440 C.CCMask = CC < 4 ? ~(~0U << (3 - CC)) : 0;
3443 C.CCMask &= CCValid;
3451 bool IsSignaling =
false) {
3454 unsigned Opcode, CCValid;
3466 Comparison
C(CmpOp0, CmpOp1, Chain);
3468 if (
C.Op0.getValueType().isFloatingPoint()) {
3472 else if (!IsSignaling)
3494 C.CCMask &= ~SystemZ::CCMASK_CMP_UO;
3515 if (!
C.Op1.getNode()) {
3517 switch (
C.Op0.getOpcode()) {
3543 EVT IntVT =
C.Op0.getValueType().changeVectorElementTypeToInteger();
3550 return DAG.
getNode(
C.Opcode,
DL, VTs,
C.Chain,
C.Op0,
C.Op1);
3552 return DAG.
getNode(
C.Opcode,
DL, MVT::i32,
C.Op0,
C.Op1);
3561 Op0 = DAG.
getNode(Extend,
DL, MVT::i64, Op0);
3562 Op1 = DAG.
getNode(Extend,
DL, MVT::i64, Op1);
3587 unsigned CCValid,
unsigned CCMask) {
3616 case CmpMode::Int:
return 0;
3636 case CmpMode::FP:
return 0;
3637 case CmpMode::StrictFP:
return 0;
3638 case CmpMode::SignalingFP:
return 0;
3670 int Mask[] = { Start, -1, Start + 1, -1 };
3690 !Subtarget.hasVectorEnhancements1()) {
3704 SDValue Ops[2] = { Res, NewChain };
3713 return DAG.
getNode(Opcode,
DL, VTs, Chain, CmpOp0, CmpOp1);
3715 return DAG.
getNode(Opcode,
DL, VT, CmpOp0, CmpOp1);
3728 bool IsSignaling)
const {
3731 assert (!IsSignaling || Chain);
3732 CmpMode Mode = IsSignaling ? CmpMode::SignalingFP :
3733 Chain ? CmpMode::StrictFP : IsFP ? CmpMode::FP : CmpMode::Int;
3734 bool Invert =
false;
3742 assert(IsFP &&
"Unexpected integer comparison");
3744 DL, VT, CmpOp1, CmpOp0, Chain);
3746 DL, VT, CmpOp0, CmpOp1, Chain);
3750 LT.getValue(1),
GE.getValue(1));
3759 assert(IsFP &&
"Unexpected integer comparison");
3761 DL, VT, CmpOp1, CmpOp0, Chain);
3763 DL, VT, CmpOp0, CmpOp1, Chain);
3767 LT.getValue(1),
GT.getValue(1));
3788 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp0, CmpOp1, Chain);
3792 Cmp = getVectorCmp(DAG, Opcode,
DL, VT, CmpOp1, CmpOp0, Chain);
3797 Chain =
Cmp.getValue(1);
3805 if (Chain && Chain.
getNode() !=
Cmp.getNode()) {
3818 EVT VT =
Op.getValueType();
3820 return lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1);
3829 bool IsSignaling)
const {
3835 EVT VT =
Op.getNode()->getValueType(0);
3837 SDValue Res = lowerVectorSETCC(DAG,
DL, VT, CC, CmpOp0, CmpOp1,
3838 Chain, IsSignaling);
3894 C.CCMask ^=
C.CCValid;
3946 cast<ConstantSDNode>(
C.Op1)->getValueSizeInBits(0) <= 64 &&
3947 C.Op1->getAsZExtVal() == 0) {
3954 if (Subtarget.hasVectorEnhancements3() &&
3956 C.Op0.getValueType() == MVT::i128 &&
3962 SDValue Ops[] = {TrueOp, FalseOp,
4036 Chain = DAG.
getCopyToReg(Chain,
DL, SystemZ::R2D, GOTOffset, Glue);
4043 Node->getValueType(0),
4055 assert(Mask &&
"Missing call preserved mask for calling convention");
4063 Chain = DAG.
getNode(Opcode,
DL, NodeTys, Ops);
4070SDValue SystemZTargetLowering::lowerThreadPointer(
const SDLoc &
DL,
4102 SDValue TP = lowerThreadPointer(
DL, DAG);
4210 if (
CP->isMachineConstantPoolEntry())
4229 unsigned Depth =
Op.getConstantOperandVal(0);
4236 int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF);
4262 unsigned Depth =
Op.getConstantOperandVal(0);
4270 SDValue FrameAddr = lowerFRAMEADDR(
Op, DAG);
4272 int Offset = TFL->getReturnAddressOffset(MF);
4283 &SystemZ::GR64BitRegClass);
4291 EVT InVT =
In.getValueType();
4292 EVT ResVT =
Op.getValueType();
4297 if (
auto *LoadN = dyn_cast<LoadSDNode>(In))
4300 LoadN->getBasePtr(), LoadN->getMemOperand());
4306 if (InVT == MVT::i32 && ResVT == MVT::f32) {
4308 if (Subtarget.hasHighWord()) {
4312 MVT::i64,
SDValue(U64, 0), In);
4320 DL, MVT::f32, Out64);
4322 if (InVT == MVT::f32 && ResVT == MVT::i32) {
4325 MVT::f64,
SDValue(U64, 0), In);
4327 if (Subtarget.hasHighWord())
4341 return lowerVASTART_XPLINK(
Op, DAG);
4343 return lowerVASTART_ELF(
Op, DAG);
4358 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4372 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4376 const unsigned NumFields = 4;
4387 for (
unsigned I = 0;
I < NumFields; ++
I) {
4392 MemOps[
I] = DAG.
getStore(Chain,
DL, Fields[
I], FieldAddr,
4404 const Value *DstSV = cast<SrcValueSDNode>(
Op.getOperand(3))->getValue();
4405 const Value *SrcSV = cast<SrcValueSDNode>(
Op.getOperand(4))->getValue();
4411 Align(8),
false,
false,
4417SystemZTargetLowering::lowerDYNAMIC_STACKALLOC(
SDValue Op,
4420 return lowerDYNAMIC_STACKALLOC_XPLINK(
Op, DAG);
4422 return lowerDYNAMIC_STACKALLOC_ELF(
Op, DAG);
4426SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_XPLINK(
SDValue Op,
4438 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4441 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4442 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4448 if (ExtraAlignSpace)
4452 bool IsSigned =
false;
4453 bool DoesNotReturn =
false;
4454 bool IsReturnValueUsed =
false;
4455 EVT VT =
Op.getValueType();
4477 if (ExtraAlignSpace) {
4489SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(
SDValue Op,
4503 uint64_t AlignVal = (RealignOpt ?
Align->getAsZExtVal() : 0);
4506 uint64_t RequiredAlign = std::max(AlignVal, StackAlign);
4507 uint64_t ExtraAlignSpace = RequiredAlign - StackAlign;
4518 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
4522 if (ExtraAlignSpace)
4530 DAG.
getVTList(MVT::i64, MVT::Other), Chain, OldSP, NeededSpace);
4546 if (RequiredAlign > StackAlign) {
4556 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
4563SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET(
4572 unsigned Opcode)
const {
4573 EVT VT =
Op.getValueType();
4579 assert(Subtarget.hasMiscellaneousExtensions2());
4584 Op.getOperand(0),
Op.getOperand(1), Even, Odd);
4590 EVT VT =
Op.getValueType();
4597 Op.getOperand(1), Ops[1], Ops[0]);
4598 else if (Subtarget.hasMiscellaneousExtensions2())
4603 Op.getOperand(0),
Op.getOperand(1), Ops[1], Ops[0]);
4627 LL, RL, Ops[1], Ops[0]);
4638 EVT VT =
Op.getValueType();
4645 Op.getOperand(1), Ops[1], Ops[0]);
4651 Op.getOperand(0),
Op.getOperand(1), Ops[1], Ops[0]);
4659 EVT VT =
Op.getValueType();
4679 EVT VT =
Op.getValueType();
4686 Op.getOperand(0),
Op.getOperand(1), Ops[1], Ops[0]);
4691 assert(
Op.getValueType() == MVT::i64 &&
"Should be 64-bit operation");
4694 SDValue Ops[] = {
Op.getOperand(0),
Op.getOperand(1)};
4703 if ((Masks[0] >> 32) == 0xffffffff &&
uint32_t(Masks[1]) == 0xffffffff)
4705 else if ((Masks[1] >> 32) == 0xffffffff &&
uint32_t(Masks[0]) == 0xffffffff)
4721 if (!isInt<16>(
Value))
4742 MVT::i64, HighOp, Low32);
4753 if (
N->getValueType(0) == MVT::i128) {
4754 unsigned BaseOp = 0;
4755 unsigned FlagOp = 0;
4756 bool IsBorrow =
false;
4757 switch (
Op.getOpcode()) {
4780 unsigned BaseOp = 0;
4781 unsigned CCValid = 0;
4782 unsigned CCMask = 0;
4784 switch (
Op.getOpcode()) {
4812 if (
N->getValueType(1) == MVT::i1)
4839 MVT VT =
N->getSimpleValueType(0);
4850 if (VT == MVT::i128) {
4851 unsigned BaseOp = 0;
4852 unsigned FlagOp = 0;
4853 bool IsBorrow =
false;
4854 switch (
Op.getOpcode()) {
4881 unsigned BaseOp = 0;
4882 unsigned CCValid = 0;
4883 unsigned CCMask = 0;
4885 switch (
Op.getOpcode()) {
4914 if (
N->getValueType(1) == MVT::i1)
4922 EVT VT =
Op.getValueType();
4924 Op =
Op.getOperand(0);
4972 if (NumSignificantBits == 0)
4978 BitSize = std::min(BitSize, OrigBitSize);
4987 for (int64_t
I = BitSize / 2;
I >= 8;
I =
I / 2) {
4989 if (BitSize != OrigBitSize)
5026 EVT RegVT =
Op.getValueType();
5028 return lowerATOMIC_LDST_I128(
Op, DAG);
5029 return lowerLoadF16(
Op, DAG);
5034 auto *
Node = cast<AtomicSDNode>(
Op.getNode());
5035 if (
Node->getMemoryVT().getSizeInBits() == 128)
5036 return lowerATOMIC_LDST_I128(
Op, DAG);
5037 return lowerStoreF16(
Op, DAG);
5042 auto *
Node = cast<AtomicSDNode>(
Op.getNode());
5044 (
Node->getMemoryVT() == MVT::i128 ||
Node->getMemoryVT() == MVT::f128) &&
5045 "Only custom lowering i128 or f128.");
5057 EVT PtrVT =
Addr.getValueType();
5058 EVT WideVT = MVT::i32;
5081 unsigned Opcode)
const {
5082 auto *
Node = cast<AtomicSDNode>(
Op.getNode());
5085 EVT NarrowVT =
Node->getMemoryVT();
5086 EVT WideVT = MVT::i32;
5087 if (NarrowVT == WideVT)
5099 if (
auto *Const = dyn_cast<ConstantSDNode>(Src2)) {
5105 SDValue AlignedAddr, BitShift, NegBitShift;
5123 SDValue Ops[] = { ChainIn, AlignedAddr, Src2, BitShift, NegBitShift,
5142 auto *
Node = cast<AtomicSDNode>(
Op.getNode());
5143 EVT MemVT =
Node->getMemoryVT();
5144 if (MemVT == MVT::i32 || MemVT == MVT::i64) {
5146 assert(
Op.getValueType() == MemVT &&
"Mismatched VTs");
5147 assert(Subtarget.hasInterlockedAccess1() &&
5148 "Should have been expanded by AtomicExpand pass.");
5154 Node->getChain(),
Node->getBasePtr(), NegSrc2,
5155 Node->getMemOperand());
5164 auto *
Node = cast<AtomicSDNode>(
Op.getNode());
5172 if (
Node->getMemoryVT() == MVT::i128) {
5181 EVT NarrowVT =
Node->getMemoryVT();
5182 EVT WideVT = NarrowVT == MVT::i64 ? MVT::i64 : MVT::i32;
5183 if (NarrowVT == WideVT) {
5185 SDValue Ops[] = { ChainIn,
Addr, CmpVal, SwapVal };
5187 DL, Tys, Ops, NarrowVT, MMO);
5201 SDValue AlignedAddr, BitShift, NegBitShift;
5206 SDValue Ops[] = { ChainIn, AlignedAddr, CmpVal, SwapVal, BitShift,
5209 VTList, Ops, NarrowVT, MMO);
5223SystemZTargetLowering::getTargetMMOFlags(
const Instruction &
I)
const {
5228 if (
auto *SI = dyn_cast<StoreInst>(&
I))
5231 if (
auto *LI = dyn_cast<LoadInst>(&
I))
5234 if (
auto *AI = dyn_cast<AtomicRMWInst>(&
I))
5237 if (
auto *AI = dyn_cast<AtomicCmpXchgInst>(&
I))
5249 "in GHC calling convention");
5251 Regs->getStackPointerRegister(),
Op.getValueType());
5262 "in GHC calling convention");
5269 if (StoreBackchain) {
5271 Chain,
DL, Regs->getStackPointerRegister(), MVT::i64);
5272 Backchain = DAG.
getLoad(MVT::i64,
DL, Chain, getBackchainAddress(OldSP, DAG),
5276 Chain = DAG.
getCopyToReg(Chain,
DL, Regs->getStackPointerRegister(), NewSP);
5279 Chain = DAG.
getStore(Chain,
DL, Backchain, getBackchainAddress(NewSP, DAG),
5287 bool IsData =
Op.getConstantOperandVal(4);
5290 return Op.getOperand(0);
5293 bool IsWrite =
Op.getConstantOperandVal(2);
5295 auto *
Node = cast<MemIntrinsicSDNode>(
Op.getNode());
5299 Node->getVTList(), Ops,
5300 Node->getMemoryVT(),
Node->getMemOperand());
5312SystemZTargetLowering::lowerINTRINSIC_W_CHAIN(
SDValue Op,
5314 unsigned Opcode, CCValid;
5316 assert(
Op->getNumValues() == 2 &&
"Expected only CC result and chain");
5327SystemZTargetLowering::lowerINTRINSIC_WO_CHAIN(
SDValue Op,
5329 unsigned Opcode, CCValid;
5332 if (
Op->getNumValues() == 1)
5334 assert(
Op->getNumValues() == 2 &&
"Expected a CC and non-CC result");
5339 unsigned Id =
Op.getConstantOperandVal(0);
5341 case Intrinsic::thread_pointer:
5342 return lowerThreadPointer(
SDLoc(
Op), DAG);
5344 case Intrinsic::s390_vpdi:
5346 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5348 case Intrinsic::s390_vperm:
5350 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5352 case Intrinsic::s390_vuphb:
5353 case Intrinsic::s390_vuphh:
5354 case Intrinsic::s390_vuphf:
5355 case Intrinsic::s390_vuphg:
5359 case Intrinsic::s390_vuplhb:
5360 case Intrinsic::s390_vuplhh:
5361 case Intrinsic::s390_vuplhf:
5362 case Intrinsic::s390_vuplhg:
5366 case Intrinsic::s390_vuplb:
5367 case Intrinsic::s390_vuplhw:
5368 case Intrinsic::s390_vuplf:
5369 case Intrinsic::s390_vuplg:
5373 case Intrinsic::s390_vupllb:
5374 case Intrinsic::s390_vupllh:
5375 case Intrinsic::s390_vupllf:
5376 case Intrinsic::s390_vupllg:
5380 case Intrinsic::s390_vsumb:
5381 case Intrinsic::s390_vsumh:
5382 case Intrinsic::s390_vsumgh:
5383 case Intrinsic::s390_vsumgf:
5384 case Intrinsic::s390_vsumqf:
5385 case Intrinsic::s390_vsumqg:
5387 Op.getOperand(1),
Op.getOperand(2));
5389 case Intrinsic::s390_vaq:
5391 Op.getOperand(1),
Op.getOperand(2));
5392 case Intrinsic::s390_vaccb:
5393 case Intrinsic::s390_vacch:
5394 case Intrinsic::s390_vaccf:
5395 case Intrinsic::s390_vaccg:
5396 case Intrinsic::s390_vaccq:
5398 Op.getOperand(1),
Op.getOperand(2));
5399 case Intrinsic::s390_vacq:
5401 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5402 case Intrinsic::s390_vacccq:
5404 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5406 case Intrinsic::s390_vsq:
5408 Op.getOperand(1),
Op.getOperand(2));
5409 case Intrinsic::s390_vscbib:
5410 case Intrinsic::s390_vscbih:
5411 case Intrinsic::s390_vscbif:
5412 case Intrinsic::s390_vscbig:
5413 case Intrinsic::s390_vscbiq:
5415 Op.getOperand(1),
Op.getOperand(2));
5416 case Intrinsic::s390_vsbiq:
5418 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5419 case Intrinsic::s390_vsbcbiq:
5421 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5423 case Intrinsic::s390_vmhb:
5424 case Intrinsic::s390_vmhh:
5425 case Intrinsic::s390_vmhf:
5426 case Intrinsic::s390_vmhg:
5427 case Intrinsic::s390_vmhq:
5429 Op.getOperand(1),
Op.getOperand(2));
5430 case Intrinsic::s390_vmlhb:
5431 case Intrinsic::s390_vmlhh:
5432 case Intrinsic::s390_vmlhf:
5433 case Intrinsic::s390_vmlhg:
5434 case Intrinsic::s390_vmlhq:
5436 Op.getOperand(1),
Op.getOperand(2));
5438 case Intrinsic::s390_vmahb:
5439 case Intrinsic::s390_vmahh:
5440 case Intrinsic::s390_vmahf:
5441 case Intrinsic::s390_vmahg:
5442 case Intrinsic::s390_vmahq:
5444 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5445 case Intrinsic::s390_vmalhb:
5446 case Intrinsic::s390_vmalhh:
5447 case Intrinsic::s390_vmalhf:
5448 case Intrinsic::s390_vmalhg:
5449 case Intrinsic::s390_vmalhq:
5451 Op.getOperand(1),
Op.getOperand(2),
Op.getOperand(3));
5453 case Intrinsic::s390_vmeb:
5454 case Intrinsic::s390_vmeh:
5455 case Intrinsic::s390_vmef:
5456 case Intrinsic::s390_vmeg:
5458 Op.getOperand(1),
Op.getOperand(2));
5459 case Intrinsic::s390_vmleb:
5460 case Intrinsic::s390_vmleh:
5461 case Intrinsic::s390_vmlef:
5462 case Intrinsic::s390_vmleg:
5464 Op.getOperand(1),
Op.getOperand(2));
5465 case Intrinsic::s390_vmob:
5466 case Intrinsic::s390_vmoh:
5467 case Intrinsic::s390_vmof:
5468 case Intrinsic::s390_vmog:
5470 Op.getOperand(1),
Op.getOperand(2));
5471 case Intrinsic::s390_vmlob:
5472 case Intrinsic::s390_vmloh:
5473 case Intrinsic::s390_vmlof:
5474 case Intrinsic::s390_vmlog:
5476 Op.getOperand(1),
Op.getOperand(2));
5478 case Intrinsic::s390_vmaeb:
5479 case Intrinsic::s390_vmaeh:
5480 case Intrinsic::s390_vmaef:
5481 case Intrinsic::s390_vmaeg:
5484 Op.getOperand(1),
Op.getOperand(2)),
5486 case Intrinsic::s390_vmaleb:
5487 case Intrinsic::s390_vmaleh:
5488 case Intrinsic::s390_vmalef:
5489 case Intrinsic::s390_vmaleg:
5492 Op.getOperand(1),
Op.getOperand(2)),
5494 case Intrinsic::s390_vmaob:
5495 case Intrinsic::s390_vmaoh:
5496 case Intrinsic::s390_vmaof:
5497 case Intrinsic::s390_vmaog:
5500 Op.getOperand(1),
Op.getOperand(2)),
5502 case Intrinsic::s390_vmalob:
5503 case Intrinsic::s390_vmaloh:
5504 case Intrinsic::s390_vmalof:
5505 case Intrinsic::s390_vmalog:
5508 Op.getOperand(1),
Op.getOperand(2)),
5530 { 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23 } },
5533 { 0, 1, 2, 3, 16, 17, 18, 19, 4, 5, 6, 7, 20, 21, 22, 23 } },
5536 { 0, 1, 16, 17, 2, 3, 18, 19, 4, 5, 20, 21, 6, 7, 22, 23 } },
5539 { 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23 } },
5542 { 8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31 } },
5545 { 8, 9, 10, 11, 24, 25, 26, 27, 12, 13, 14, 15, 28, 29, 30, 31 } },
5548 { 8, 9, 24, 25, 10, 11, 26, 27, 12, 13, 28, 29, 14, 15, 30, 31 } },
5551 { 8, 24, 9, 25, 10, 26, 11, 27, 12, 28, 13, 29, 14, 30, 15, 31 } },
5554 { 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 } },
5557 { 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31 } },
5560 { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31 } },
5563 { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 } },
5566 { 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31 } }
5580 OpNo0 = OpNo1 = OpNos[1];
5581 }
else if (OpNos[1] < 0) {
5582 OpNo0 = OpNo1 = OpNos[0];
5600 unsigned &OpNo0,
unsigned &OpNo1) {
5601 int OpNos[] = { -1, -1 };
5614 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5616 OpNos[ModelOpNo] = RealOpNo;
5624 unsigned &OpNo0,
unsigned &OpNo1) {
5641 int Elt = Bytes[
From];
5644 Transform[
From] = -1;
5646 while (
P.Bytes[To] != Elt) {
5651 Transform[
From] = To;
5674 if (
auto *VSN = dyn_cast<ShuffleVectorSDNode>(ShuffleOp)) {
5675 Bytes.
resize(NumElements * BytesPerElement, -1);
5676 for (
unsigned I = 0;
I < NumElements; ++
I) {
5677 int Index = VSN->getMaskElt(
I);
5679 for (
unsigned J = 0; J < BytesPerElement; ++J)
5680 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5685 isa<ConstantSDNode>(ShuffleOp.
getOperand(1))) {
5687 Bytes.
resize(NumElements * BytesPerElement, -1);
5688 for (
unsigned I = 0;
I < NumElements; ++
I)
5689 for (
unsigned J = 0; J < BytesPerElement; ++J)
5690 Bytes[
I * BytesPerElement + J] = Index * BytesPerElement + J;
5701 unsigned BytesPerElement,
int &
Base) {
5703 for (
unsigned I = 0;
I < BytesPerElement; ++
I) {
5704 if (Bytes[Start +
I] >= 0) {
5705 unsigned Elem = Bytes[Start +
I];
5709 if (
unsigned(
Base) % Bytes.
size() + BytesPerElement > Bytes.
size())
5711 }
else if (
unsigned(
Base) != Elem -
I)
5724 unsigned &StartIndex,
unsigned &OpNo0,
5726 int OpNos[] = { -1, -1 };
5728 for (
unsigned I = 0;
I < 16; ++
I) {
5729 int Index = Bytes[
I];
5735 Shift = ExpectedShift;
5736 else if (Shift != ExpectedShift)
5740 if (OpNos[ModelOpNo] == 1 - RealOpNo)
5742 OpNos[ModelOpNo] = RealOpNo;
5779 N =
N->getOperand(0);
5781 if (
auto *
Op = dyn_cast<ConstantSDNode>(
N->getOperand(0)))
5782 return Op->getZExtValue() == 0;
5788 for (
unsigned I = 0;
I < Num ;
I++)
5800 for (
unsigned I = 0;
I < 2; ++
I)
5804 unsigned StartIndex, OpNo0, OpNo1;
5813 if (ZeroVecIdx != UINT32_MAX) {
5814 bool MaskFirst =
true;
5819 if (OpNo == ZeroVecIdx &&
I == 0) {
5824 if (OpNo != ZeroVecIdx && Byte == 0) {
5831 if (ZeroIdx != -1) {
5834 if (Bytes[
I] >= 0) {
5837 if (OpNo == ZeroVecIdx)
5847 SDValue Src = ZeroVecIdx == 0 ? Ops[1] : Ops[0];
5865 (!Ops[1].
isUndef() ? Ops[1] : Ops[0]), Op2);
5870struct GeneralShuffle {
5871 GeneralShuffle(
EVT vt)
5872 : VT(vt), UnpackFromEltSize(UINT_MAX), UnpackLow(
false) {}
5876 void tryPrepareForUnpack();
5877 bool unpackWasPrepared() {
return UnpackFromEltSize <= 4; }
5892 unsigned UnpackFromEltSize;
5899void GeneralShuffle::addUndef() {
5901 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5902 Bytes.push_back(-1);
5911bool GeneralShuffle::add(
SDValue Op,
unsigned Elem) {
5917 EVT FromVT =
Op.getNode() ?
Op.getValueType() : VT;
5922 if (FromBytesPerElement < BytesPerElement)
5926 (FromBytesPerElement - BytesPerElement));
5929 while (
Op.getNode()) {
5931 Op =
Op.getOperand(0);
5947 }
else if (
Op.isUndef()) {
5956 for (; OpNo < Ops.size(); ++OpNo)
5957 if (Ops[OpNo] ==
Op)
5959 if (OpNo == Ops.size())
5964 for (
unsigned I = 0;
I < BytesPerElement; ++
I)
5965 Bytes.push_back(
Base +
I);
5974 if (Ops.size() == 0)
5978 tryPrepareForUnpack();
5981 if (Ops.size() == 1)
5982 Ops.push_back(DAG.
getUNDEF(MVT::v16i8));
5993 unsigned Stride = 1;
5994 for (; Stride * 2 < Ops.size(); Stride *= 2) {
5995 for (
unsigned I = 0;
I < Ops.size() - Stride;
I += Stride * 2) {
5996 SDValue SubOps[] = { Ops[
I], Ops[
I + Stride] };
6005 else if (OpNo ==
I + Stride)
6016 if (NewBytes[J] >= 0) {
6018 "Invalid double permute");
6021 assert(NewBytesMap[J] < 0 &&
"Invalid double permute");
6027 if (NewBytes[J] >= 0)
6035 Ops[1] = Ops[Stride];
6043 unsigned OpNo0, OpNo1;
6045 if (unpackWasPrepared() && Ops[1].
isUndef())
6047 else if (
const Permute *
P =
matchPermute(Bytes, OpNo0, OpNo1))
6052 Op = insertUnpackIfPrepared(DAG,
DL,
Op);
6059 dbgs() << Msg.c_str() <<
" { ";
6060 for (
unsigned I = 0;
I < Bytes.
size();
I++)
6061 dbgs() << Bytes[
I] <<
" ";
6069void GeneralShuffle::tryPrepareForUnpack() {
6071 if (ZeroVecOpNo == UINT32_MAX || Ops.size() == 1)
6076 if (Ops.size() > 2 &&
6081 UnpackFromEltSize = 1;
6082 for (; UnpackFromEltSize <= 4; UnpackFromEltSize *= 2) {
6083 bool MatchUnpack =
true;
6086 unsigned ToEltSize = UnpackFromEltSize * 2;
6087 bool IsZextByte = (Elt % ToEltSize) < UnpackFromEltSize;
6090 if (Bytes[Elt] != -1) {
6092 if (IsZextByte != (OpNo == ZeroVecOpNo)) {
6093 MatchUnpack =
false;
6099 if (Ops.size() == 2) {
6101 bool CanUseUnpackLow =
true, CanUseUnpackHigh =
true;
6103 if (SrcBytes[i] == -1)
6105 if (SrcBytes[i] % 16 !=
int(i))
6106 CanUseUnpackHigh =
false;
6108 CanUseUnpackLow =
false;
6109 if (!CanUseUnpackLow && !CanUseUnpackHigh) {
6110 UnpackFromEltSize = UINT_MAX;
6114 if (!CanUseUnpackHigh)
6120 if (UnpackFromEltSize > 4)
6123 LLVM_DEBUG(
dbgs() <<
"Preparing for final unpack of element size "
6124 << UnpackFromEltSize <<
". Zero vector is Op#" << ZeroVecOpNo
6126 dumpBytes(Bytes,
"Original Bytes vector:"););
6135 Elt += UnpackFromEltSize;
6136 for (
unsigned i = 0; i < UnpackFromEltSize; i++, Elt++,
B++)
6137 Bytes[
B] = Bytes[Elt];
6145 Ops.erase(&Ops[ZeroVecOpNo]);
6147 if (Bytes[
I] >= 0) {
6149 if (OpNo > ZeroVecOpNo)
6160 if (!unpackWasPrepared())
6162 unsigned InBits = UnpackFromEltSize * 8;
6166 unsigned OutBits = InBits * 2;
6171 DL, OutVT, PackedOp);
6177 if (!
Op.getOperand(
I).isUndef())
6193 if (
Value.isUndef())
6246 GeneralShuffle GS(VT);
6248 bool FoundOne =
false;
6249 for (
unsigned I = 0;
I < NumElements; ++
I) {
6252 Op =
Op.getOperand(0);
6255 unsigned Elem =
Op.getConstantOperandVal(1);
6256 if (!GS.add(
Op.getOperand(0), Elem))
6259 }
else if (
Op.isUndef()) {
6273 if (!ResidueOps.
empty()) {
6274 while (ResidueOps.
size() < NumElements)
6276 for (
auto &
Op : GS.Ops) {
6277 if (!
Op.getNode()) {
6283 return GS.getNode(DAG,
SDLoc(BVN));
6286bool SystemZTargetLowering::isVectorElementLoad(
SDValue Op)
const {
6287 if (
Op.getOpcode() ==
ISD::LOAD && cast<LoadSDNode>(
Op)->isUnindexed())
6289 if (
auto *AL = dyn_cast<AtomicSDNode>(
Op))
6303 unsigned int NumElements = Elems.
size();
6304 unsigned int Count = 0;
6305 for (
auto Elem : Elems) {
6306 if (!Elem.isUndef()) {
6309 else if (Elem != Single) {
6329 if (
Single.getNode() && (Count > 1 || isVectorElementLoad(Single)))
6333 bool AllLoads =
true;
6334 for (
auto Elem : Elems)
6335 if (!isVectorElementLoad(Elem)) {
6341 if (VT == MVT::v2i64 && !AllLoads)
6345 if (VT == MVT::v2f64 && !AllLoads)
6355 if (VT == MVT::v4f32 && !AllLoads) {
6369 DL, MVT::v2i64, Op01, Op23);
6377 unsigned NumConstants = 0;
6378 for (
unsigned I = 0;
I < NumElements; ++
I) {
6392 if (NumConstants > 0) {
6393 for (
unsigned I = 0;
I < NumElements; ++
I)
6404 std::map<const SDNode*, unsigned> UseCounts;
6405 SDNode *LoadMaxUses =
nullptr;
6406 for (
unsigned I = 0;
I < NumElements; ++
I)
6407 if (isVectorElementLoad(Elems[
I])) {
6408 SDNode *Ld = Elems[
I].getNode();
6409 unsigned Count = ++UseCounts[Ld];
6410 if (LoadMaxUses ==
nullptr || UseCounts[LoadMaxUses] < Count)
6413 if (LoadMaxUses !=
nullptr) {
6414 ReplicatedVal =
SDValue(LoadMaxUses, 0);
6418 unsigned I1 = NumElements / 2 - 1;
6419 unsigned I2 = NumElements - 1;
6420 bool Def1 = !Elems[
I1].isUndef();
6421 bool Def2 = !Elems[I2].isUndef();
6435 for (
unsigned I = 0;
I < NumElements; ++
I)
6436 if (!
Done[
I] && !Elems[
I].
isUndef() && Elems[
I] != ReplicatedVal)
6444 auto *BVN = cast<BuildVectorSDNode>(
Op.getNode());
6446 EVT VT =
Op.getValueType();
6448 if (BVN->isConstant()) {
6467 for (
unsigned I = 0;
I < NumElements; ++
I)
6468 Ops[
I] =
Op.getOperand(
I);
6469 return buildVector(DAG,
DL, VT, Ops);
6474 auto *VSN = cast<ShuffleVectorSDNode>(
Op.getNode());
6476 EVT VT =
Op.getValueType();
6479 if (VSN->isSplat()) {
6481 unsigned Index = VSN->getSplatIndex();
6483 "Splat index should be defined and in first operand");
6493 GeneralShuffle
GS(VT);
6494 for (
unsigned I = 0;
I < NumElements; ++
I) {
6495 int Elt = VSN->getMaskElt(
I);
6498 else if (!
GS.add(
Op.getOperand(
unsigned(Elt) / NumElements),
6499 unsigned(Elt) % NumElements))
6502 return GS.getNode(DAG,
SDLoc(VSN));
6521 EVT VT =
Op.getValueType();
6526 if (VT == MVT::v2f64 &&
6546SystemZTargetLowering::lowerEXTRACT_VECTOR_ELT(
SDValue Op,
6552 EVT VT =
Op.getValueType();
6556 if (
auto *CIndexN = dyn_cast<ConstantSDNode>(Op1)) {
6571SDValue SystemZTargetLowering::
6574 EVT OutVT =
Op.getValueType();
6578 unsigned StartOffset = 0;
6590 if (ToBits == 64 && OutNumElts == 2) {
6591 int NumElem = ToBits / FromBits;
6592 if (ShuffleMask[0] == NumElem - 1 && ShuffleMask[1] == 2 * NumElem - 1)
6598 int StartOffsetCandidate = -1;
6599 for (
int Elt = 0; Elt < OutNumElts; Elt++) {
6600 if (ShuffleMask[Elt] == -1)
6602 if (ShuffleMask[Elt] % OutNumElts == Elt) {
6603 if (StartOffsetCandidate == -1)
6604 StartOffsetCandidate = ShuffleMask[Elt] - Elt;
6605 if (StartOffsetCandidate == ShuffleMask[Elt] - Elt)
6608 StartOffsetCandidate = -1;
6611 if (StartOffsetCandidate != -1) {
6612 StartOffset = StartOffsetCandidate;
6622 if (StartOffset >= OutNumElts) {
6624 StartOffset -= OutNumElts;
6626 PackedOp = DAG.
getNode(Opcode,
SDLoc(PackedOp), OutVT, PackedOp);
6627 }
while (FromBits != ToBits);
6632SDValue SystemZTargetLowering::
6636 EVT OutVT =
Op.getValueType();
6640 unsigned NumInPerOut = InNumElts / OutNumElts;
6646 unsigned ZeroVecElt = InNumElts;
6647 for (
unsigned PackedElt = 0; PackedElt < OutNumElts; PackedElt++) {
6648 unsigned MaskElt = PackedElt * NumInPerOut;
6649 unsigned End = MaskElt + NumInPerOut - 1;
6650 for (; MaskElt <
End; MaskElt++)
6651 Mask[MaskElt] = ZeroVecElt++;
6652 Mask[MaskElt] = PackedElt;
6659 unsigned ByScalar)
const {
6664 EVT VT =
Op.getValueType();
6668 if (
auto *BVN = dyn_cast<BuildVectorSDNode>(Op1)) {
6669 APInt SplatBits, SplatUndef;
6670 unsigned SplatBitSize;
6674 if (BVN->isConstantSplat(SplatBits, SplatUndef, SplatBitSize, HasAnyUndefs,
6675 ElemBitSize,
true) &&
6676 SplatBitSize == ElemBitSize) {
6679 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6688 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6694 if (
auto *VSN = dyn_cast<ShuffleVectorSDNode>(Op1)) {
6695 if (VSN->isSplat()) {
6697 unsigned Index = VSN->getSplatIndex();
6699 "Splat index should be defined and in first operand");
6706 return DAG.
getNode(ByScalar,
DL, VT, Op0, Shift);
6723 if (
auto *ShiftAmtNode = dyn_cast<ConstantSDNode>(
Op.getOperand(2))) {
6724 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6725 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6728 if (ShiftAmt > 120) {
6737 for (
unsigned Elt = 0; Elt < 16; Elt++)
6738 Mask[Elt] = (ShiftAmt >> 3) + Elt;
6740 if ((ShiftAmt & 7) == 0)
6761 if (
auto *ShiftAmtNode = dyn_cast<ConstantSDNode>(
Op.getOperand(2))) {
6762 uint64_t ShiftAmt = ShiftAmtNode->getZExtValue() & 127;
6763 if ((ShiftAmt & 7) == 0 || Subtarget.hasVectorEnhancements2()) {
6766 if (ShiftAmt > 120) {
6775 for (
unsigned Elt = 0; Elt < 16; Elt++)
6776 Mask[Elt] = 16 - (ShiftAmt >> 3) + Elt;
6778 if ((ShiftAmt & 7) == 0)
6794 MVT DstVT =
Op.getSimpleValueType();
6797 unsigned SrcAS =
N->getSrcAddressSpace();
6799 assert(SrcAS !=
N->getDestAddressSpace() &&
6800 "addrspacecast must be between different address spaces");
6808 }
else if (DstVT == MVT::i32) {
6822 if (
In.getSimpleValueType() != MVT::f16)
6829 SDValue Chain,
bool IsStrict)
const {
6830 assert(LC != RTLIB::UNKNOWN_LIBCALL &&
"Unexpected request for libcall!");
6833 std::tie(Result, Chain) =
6842 bool IsStrict =
Op->isStrictFPOpcode();
6844 MVT VT =
Op.getSimpleValueType();
6845 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6853 if (!Subtarget.hasFPExtension() && !IsSigned)
6864 if (VT == MVT::i128) {
6867 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6877 bool IsStrict =
Op->isStrictFPOpcode();
6879 MVT VT =
Op.getSimpleValueType();
6880 SDValue InOp =
Op.getOperand(IsStrict ? 1 : 0);
6885 if (VT == MVT::f16) {
6892 if (!Subtarget.hasFPExtension() && !IsSigned)
6895 if (InVT == MVT::i128) {
6898 return useLibCall(DAG, LC, VT, InOp,
DL, Chain, IsStrict);
6907 assert(
Op.getSimpleValueType() == MVT::i64 &&
6908 "Expexted to convert i64 to f16.");
6920 assert(
Op.getSimpleValueType() == MVT::f16 &&
6921 "Expected to convert f16 to i64.");
6934 EVT RegVT =
Op.getValueType();
6935 assert(RegVT == MVT::f16 &&
"Expected to lower an f16 load.");
6941 if (
auto *AtomicLd = dyn_cast<AtomicSDNode>(
Op.getNode())) {
6942 assert(
EVT(RegVT) == AtomicLd->getMemoryVT() &&
"Unhandled f16 load");
6944 AtomicLd->getChain(), AtomicLd->getBasePtr(),
6945 AtomicLd->getMemOperand());
6963 if (
auto *AtomicSt = dyn_cast<AtomicSDNode>(
Op.getNode()))
6965 Shft, AtomicSt->getBasePtr(),
6966 AtomicSt->getMemOperand());
6976 MVT ResultVT =
Op.getSimpleValueType();
6978 unsigned Check =
Op.getConstantOperandVal(1);
6980 unsigned TDCMask = 0;
7016 int SPFI = cast<FrameIndexSDNode>(
StackPtr.getNode())->getIndex();
7027 return DAG.
getLoad(MVT::i64,
DL, Chain, StackPtr, MPI);
7032 switch (
Op.getOpcode()) {
7034 return lowerFRAMEADDR(
Op, DAG);
7036 return lowerRETURNADDR(
Op, DAG);
7038 return lowerBR_CC(
Op, DAG);
7040 return lowerSELECT_CC(
Op, DAG);
7042 return lowerSETCC(
Op, DAG);
7044 return lowerSTRICT_FSETCC(
Op, DAG,
false);
7046 return lowerSTRICT_FSETCC(
Op, DAG,
true);
7048 return lowerGlobalAddress(cast<GlobalAddressSDNode>(
Op), DAG);
7050 return lowerGlobalTLSAddress(cast<GlobalAddressSDNode>(
Op), DAG);
7052 return lowerBlockAddress(cast<BlockAddressSDNode>(
Op), DAG);
7054 return lowerJumpTable(cast<JumpTableSDNode>(
Op), DAG);
7056 return lowerConstantPool(cast<ConstantPoolSDNode>(
Op), DAG);
7058 return lowerBITCAST(
Op, DAG);
7060 return lowerVASTART(
Op, DAG);
7062 return lowerVACOPY(
Op, DAG);
7064 return lowerDYNAMIC_STACKALLOC(
Op, DAG);
7066 return lowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
7072 return lowerSMUL_LOHI(
Op, DAG);
7074 return lowerUMUL_LOHI(
Op, DAG);
7076 return lowerSDIVREM(
Op, DAG);
7078 return lowerUDIVREM(
Op, DAG);
7083 return lowerXALUO(
Op, DAG);
7086 return lowerUADDSUBO_CARRY(
Op, DAG);
7088 return lowerOR(
Op, DAG);
7090 return lowerCTPOP(
Op, DAG);
7092 return lowerVECREDUCE_ADD(
Op, DAG);
7094 return lowerATOMIC_FENCE(
Op, DAG);
7098 return lowerATOMIC_STORE(
Op, DAG);
7100 return lowerATOMIC_LOAD(
Op, DAG);
7104 return lowerATOMIC_LOAD_SUB(
Op, DAG);
7122 return lowerATOMIC_CMP_SWAP(
Op, DAG);
7124 return lowerSTACKSAVE(
Op, DAG);
7126 return lowerSTACKRESTORE(
Op, DAG);
7128 return lowerPREFETCH(
Op, DAG);
7130 return lowerINTRINSIC_W_CHAIN(
Op, DAG);
7132 return lowerINTRINSIC_WO_CHAIN(
Op, DAG);
7134 return lowerBUILD_VECTOR(
Op, DAG);
7136 return lowerVECTOR_SHUFFLE(
Op, DAG);
7138 return lowerSCALAR_TO_VECTOR(
Op, DAG);
7140 return lowerINSERT_VECTOR_ELT(
Op, DAG);
7142 return lowerEXTRACT_VECTOR_ELT(
Op, DAG);
7144 return lowerSIGN_EXTEND_VECTOR_INREG(
Op, DAG);
7146 return lowerZERO_EXTEND_VECTOR_INREG(
Op, DAG);
7158 return lowerFSHL(
Op, DAG);
7160 return lowerFSHR(
Op, DAG);
7163 return lowerFP_EXTEND(
Op, DAG);
7168 return lower_FP_TO_INT(
Op, DAG);
7173 return lower_INT_TO_FP(
Op, DAG);
7175 return lowerLoadF16(
Op, DAG);
7177 return lowerStoreF16(
Op, DAG);
7179 return lowerIS_FPCLASS(
Op, DAG);
7181 return lowerGET_ROUNDING(
Op, DAG);
7183 return lowerREADCYCLECOUNTER(
Op, DAG);
7205 &SystemZ::FP128BitRegClass);
7214 SystemZ::REG_SEQUENCE, SL, MVT::f128,
7229 &SystemZ::FP128BitRegClass);
7246 switch (
N->getOpcode()) {
7250 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1) };
7253 DL, Tys, Ops, MVT::i128, MMO);
7256 if (
N->getValueType(0) == MVT::f128)
7270 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2)};
7273 DL, Tys, Ops, MVT::i128, MMO);
7276 if (cast<AtomicSDNode>(
N)->getSuccessOrdering() ==
7279 MVT::Other, Res), 0);
7286 SDValue Ops[] = {
N->getOperand(0),
N->getOperand(1),
7291 DL, Tys, Ops, MVT::i128, MMO);
7305 EVT SrcVT = Src.getValueType();
7306 EVT ResVT =
N->getValueType(0);
7307 if (ResVT == MVT::i128 && SrcVT == MVT::f128)
7309 else if (SrcVT == MVT::i16 && ResVT == MVT::f16) {
7310 if (Subtarget.hasVector()) {
7318 }
else if (SrcVT == MVT::f16 && ResVT == MVT::i16) {
7320 Subtarget.hasVector()
7334 bool IsStrict =
N->isStrictFPOpcode();
7336 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7337 EVT ResVT =
N->getValueType(0);
7339 if (ResVT == MVT::f16) {
7362 bool IsStrict =
N->isStrictFPOpcode();
7364 EVT ResVT =
N->getValueType(0);
7365 SDValue InOp =
N->getOperand(IsStrict ? 1 : 0);
7368 if (InVT == MVT::f16) {
7374 std::tie(InF32, Chain) =
7398#define OPCODE(NAME) case SystemZISD::NAME: return "SystemZISD::" #NAME
7517 OPCODE(ATOMIC_LOADW_ADD);
7518 OPCODE(ATOMIC_LOADW_SUB);
7519 OPCODE(ATOMIC_LOADW_AND);
7521 OPCODE(ATOMIC_LOADW_XOR);
7522 OPCODE(ATOMIC_LOADW_NAND);
7523 OPCODE(ATOMIC_LOADW_MIN);
7524 OPCODE(ATOMIC_LOADW_MAX);
7525 OPCODE(ATOMIC_LOADW_UMIN);
7526 OPCODE(ATOMIC_LOADW_UMAX);
7527 OPCODE(ATOMIC_CMP_SWAPW);
7530 OPCODE(ATOMIC_STORE_128);
7531 OPCODE(ATOMIC_CMP_SWAP_128);
7546bool SystemZTargetLowering::canTreatAsByteVector(
EVT VT)
const {
7547 if (!Subtarget.hasVector())
7561 DAGCombinerInfo &DCI,
7569 unsigned Opcode =
Op.getOpcode();
7572 Op =
Op.getOperand(0);
7574 canTreatAsByteVector(
Op.getValueType())) {
7583 BytesPerElement,
First))
7590 if (Byte % BytesPerElement != 0)
7593 Index = Byte / BytesPerElement;
7597 canTreatAsByteVector(
Op.getValueType())) {
7600 EVT OpVT =
Op.getValueType();
7602 if (OpBytesPerElement < BytesPerElement)
7606 unsigned End = (
Index + 1) * BytesPerElement;
7607 if (
End % OpBytesPerElement != 0)
7610 Op =
Op.getOperand(
End / OpBytesPerElement - 1);
7611 if (!
Op.getValueType().isInteger()) {
7614 DCI.AddToWorklist(
Op.getNode());
7619 DCI.AddToWorklist(
Op.getNode());
7626 canTreatAsByteVector(
Op.getValueType()) &&
7627 canTreatAsByteVector(
Op.getOperand(0).getValueType())) {
7629 EVT ExtVT =
Op.getValueType();
7630 EVT OpVT =
Op.getOperand(0).getValueType();
7633 unsigned Byte =
Index * BytesPerElement;
7634 unsigned SubByte =
Byte % ExtBytesPerElement;
7635 unsigned MinSubByte = ExtBytesPerElement - OpBytesPerElement;
7636 if (SubByte < MinSubByte ||
7637 SubByte + BytesPerElement > ExtBytesPerElement)
7640 Byte =
Byte / ExtBytesPerElement * OpBytesPerElement;
7642 Byte += SubByte - MinSubByte;
7643 if (Byte % BytesPerElement != 0)
7645 Op =
Op.getOperand(0);
7652 if (
Op.getValueType() != VecVT) {
7654 DCI.AddToWorklist(
Op.getNode());
7664SDValue SystemZTargetLowering::combineTruncateExtract(
7673 if (canTreatAsByteVector(VecVT)) {
7674 if (
auto *IndexN = dyn_cast<ConstantSDNode>(
Op.getOperand(1))) {
7677 if (BytesPerElement % TruncBytes == 0) {
7683 unsigned Scale = BytesPerElement / TruncBytes;
7684 unsigned NewIndex = (IndexN->getZExtValue() + 1) * Scale - 1;
7691 EVT ResVT = (TruncBytes < 4 ? MVT::i32 : TruncVT);
7692 return combineExtract(
DL, ResVT, VecVT, Vec, NewIndex, DCI,
true);
7700SDValue SystemZTargetLowering::combineZERO_EXTEND(
7701 SDNode *
N, DAGCombinerInfo &DCI)
const {
7705 EVT VT =
N->getValueType(0);
7707 auto *TrueOp = dyn_cast<ConstantSDNode>(N0.
getOperand(0));
7708 auto *FalseOp = dyn_cast<ConstantSDNode>(N0.
getOperand(1));
7709 if (TrueOp && FalseOp) {
7719 DCI.CombineTo(N0.
getNode(), TruncSelect);
7780SDValue SystemZTargetLowering::combineSIGN_EXTEND_INREG(
7781 SDNode *
N, DAGCombinerInfo &DCI)
const {
7787 EVT VT =
N->getValueType(0);
7788 EVT EVT = cast<VTSDNode>(
N->getOperand(1))->getVT();
7801SDValue SystemZTargetLowering::combineSIGN_EXTEND(
7802 SDNode *
N, DAGCombinerInfo &DCI)
const {
7808 EVT VT =
N->getValueType(0);
7810 auto *SraAmt = dyn_cast<ConstantSDNode>(N0.
getOperand(1));
7813 if (
auto *ShlAmt = dyn_cast<ConstantSDNode>(Inner.
getOperand(1))) {
7815 unsigned NewShlAmt = ShlAmt->getZExtValue() + Extra;
7816 unsigned NewSraAmt = SraAmt->getZExtValue() + Extra;
7832SDValue SystemZTargetLowering::combineMERGE(
7833 SDNode *
N, DAGCombinerInfo &DCI)
const {
7835 unsigned Opcode =
N->getOpcode();
7843 if (Op1 ==
N->getOperand(0))
7848 if (ElemBytes <= 4) {
7856 DCI.AddToWorklist(Op1.
getNode());
7859 DCI.AddToWorklist(
Op.getNode());
7868 LoPart = HiPart =
nullptr;
7873 if (
Use.getResNo() != 0)
7878 bool IsLoPart =
true;
7903 LoPart = HiPart =
nullptr;
7908 if (
Use.getResNo() != 0)
7914 User->getMachineOpcode() != TargetOpcode::EXTRACT_SUBREG)
7917 switch (
User->getConstantOperandVal(1)) {
7918 case SystemZ::subreg_l64:
7923 case SystemZ::subreg_h64:
7935SDValue SystemZTargetLowering::combineLOAD(
7936 SDNode *
N, DAGCombinerInfo &DCI)
const {
7938 EVT LdVT =
N->getValueType(0);
7939 if (
auto *LN = dyn_cast<LoadSDNode>(
N)) {
7942 MVT LoadNodeVT = LN->getBasePtr().getSimpleValueType();
7943 if (PtrVT != LoadNodeVT) {
7947 return DAG.
getExtLoad(LN->getExtensionType(),
DL, LN->getValueType(0),
7948 LN->getChain(), AddrSpaceCast, LN->getMemoryVT(),
7949 LN->getMemOperand());
7967 LD->getPointerInfo(),
LD->getBaseAlign(),
7968 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7970 DCI.CombineTo(HiPart, EltLoad,
true);
7977 LD->getPointerInfo().getWithOffset(8),
LD->getBaseAlign(),
7978 LD->getMemOperand()->getFlags(),
LD->getAAInfo());
7980 DCI.CombineTo(LoPart, EltLoad,
true);
7987 DCI.AddToWorklist(Chain.
getNode());
8007 }
else if (
Use.getResNo() == 0)
8010 if (!Replicate || OtherUses.
empty())
8016 for (
SDNode *U : OtherUses) {
8025bool SystemZTargetLowering::canLoadStoreByteSwapped(
EVT VT)
const {
8026 if (VT == MVT::i16 || VT == MVT::i32 || VT == MVT::i64)
8028 if (Subtarget.hasVectorEnhancements2())
8029 if (VT == MVT::v8i16 || VT == MVT::v4i32 || VT == MVT::v2i64 || VT == MVT::i128)
8041 for (
unsigned i = 0; i < NumElts; ++i) {
8042 if (M[i] < 0)
continue;
8043 if ((
unsigned) M[i] != NumElts - 1 - i)
8051 for (
auto *U : StoredVal->
users()) {
8053 EVT CurrMemVT = ST->getMemoryVT().getScalarType();
8056 }
else if (isa<BuildVectorSDNode>(U)) {
8112SDValue SystemZTargetLowering::combineSTORE(
8113 SDNode *
N, DAGCombinerInfo &DCI)
const {
8115 auto *SN = cast<StoreSDNode>(
N);
8116 auto &Op1 =
N->getOperand(1);
8117 EVT MemVT = SN->getMemoryVT();
8121 MVT StoreNodeVT = SN->getBasePtr().getSimpleValueType();
8122 if (PtrVT != StoreNodeVT) {
8126 return DAG.
getStore(SN->getChain(),
DL, SN->getValue(), AddrSpaceCast,
8127 SN->getPointerInfo(), SN->getBaseAlign(),
8128 SN->getMemOperand()->getFlags(), SN->getAAInfo());
8136 if (MemVT.
isInteger() && SN->isTruncatingStore()) {
8138 combineTruncateExtract(
SDLoc(
N), MemVT, SN->getValue(), DCI)) {
8139 DCI.AddToWorklist(
Value.getNode());
8143 SN->getBasePtr(), SN->getMemoryVT(),
8144 SN->getMemOperand());
8148 if (!SN->isTruncatingStore() &&
8159 N->getOperand(0), BSwapOp,
N->getOperand(2)
8164 Ops, MemVT, SN->getMemOperand());
8167 if (!SN->isTruncatingStore() &&
8170 Subtarget.hasVectorEnhancements2()) {
8180 Ops, MemVT, SN->getMemOperand());
8185 if (!SN->isTruncatingStore() &&
8188 N->getOperand(0).reachesChainWithoutSideEffects(
SDValue(Op1.
getNode(), 1))) {
8192 Ops, MemVT, SN->getMemOperand());
8202 SN->getChain(),
DL, HiPart, SN->getBasePtr(), SN->getPointerInfo(),
8203 SN->getBaseAlign(), SN->getMemOperand()->getFlags(), SN->getAAInfo());
8205 SN->getChain(),
DL, LoPart,
8207 SN->getPointerInfo().getWithOffset(8), SN->getBaseAlign(),
8208 SN->getMemOperand()->
getFlags(), SN->getAAInfo());
8228 if (
C->getAPIntValue().getBitWidth() > 64 ||
C->isAllOnes() ||
8232 APInt Val =
C->getAPIntValue();
8235 assert(SN->isTruncatingStore() &&
8236 "Non-truncating store and immediate value does not fit?");
8237 Val = Val.
trunc(TotBytes * 8);
8241 if (VCI.isVectorConstantLegal(Subtarget) &&
8250 auto FindReplicatedReg = [&](
SDValue MulOp) {
8251 EVT MulVT = MulOp.getValueType();
8252 if (MulOp->getOpcode() ==
ISD::MUL &&
8253 (MulVT == MVT::i16 || MulVT == MVT::i32 || MulVT == MVT::i64)) {
8257 WordVT =
LHS->getOperand(0).getValueType();
8259 WordVT = cast<VTSDNode>(
LHS->getOperand(1))->getVT();
8263 if (
auto *
C = dyn_cast<ConstantSDNode>(MulOp->getOperand(1))) {
8265 APInt(MulVT.getSizeInBits(),
C->getZExtValue()));
8266 if (VCI.isVectorConstantLegal(Subtarget) &&
8268 WordVT == VCI.VecVT.getScalarType())
8274 if (isa<BuildVectorSDNode>(Op1) &&
8277 if (
auto *
C = dyn_cast<ConstantSDNode>(SplatVal))
8280 FindReplicatedReg(SplatVal);
8282 if (
auto *
C = dyn_cast<ConstantSDNode>(Op1))
8285 FindReplicatedReg(Op1);
8290 "Bad type handling");
8295 SN->getBasePtr(), SN->getMemOperand());
8302SDValue SystemZTargetLowering::combineVECTOR_SHUFFLE(
8303 SDNode *
N, DAGCombinerInfo &DCI)
const {
8307 N->getOperand(0).hasOneUse() &&
8308 Subtarget.hasVectorEnhancements2()) {
8323 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8327 DCI.CombineTo(
N, ESLoad);
8331 DCI.CombineTo(
Load.getNode(), ESLoad, ESLoad.
getValue(1));
8341SDValue SystemZTargetLowering::combineEXTRACT_VECTOR_ELT(
8342 SDNode *
N, DAGCombinerInfo &DCI)
const {
8345 if (!Subtarget.hasVector())
8351 Op.getValueType().isVector() &&
8352 Op.getOperand(0).getValueType().isVector() &&
8353 Op.getValueType().getVectorNumElements() ==
8354 Op.getOperand(0).getValueType().getVectorNumElements())
8355 Op =
Op.getOperand(0);
8359 EVT VecVT =
Op.getValueType();
8362 Op.getOperand(0),
N->getOperand(1));
8363 DCI.AddToWorklist(
Op.getNode());
8365 if (EltVT !=
N->getValueType(0)) {
8366 DCI.AddToWorklist(
Op.getNode());
8373 if (
auto *IndexN = dyn_cast<ConstantSDNode>(
N->getOperand(1))) {
8376 if (canTreatAsByteVector(VecVT))
8377 return combineExtract(
SDLoc(
N),
N->getValueType(0), VecVT, Op0,
8378 IndexN->getZExtValue(), DCI,
false);
8383SDValue SystemZTargetLowering::combineJOIN_DWORDS(
8384 SDNode *
N, DAGCombinerInfo &DCI)
const {
8387 if (
N->getOperand(0) ==
N->getOperand(1))
8398 if (Chain1 == Chain2)
8406SDValue SystemZTargetLowering::combineFP_ROUND(
8407 SDNode *
N, DAGCombinerInfo &DCI)
const {
8409 if (!Subtarget.hasVector())
8418 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8421 if (
N->getValueType(0) == MVT::f32 && Op0.
hasOneUse() &&
8427 for (
auto *U : Vec->
users()) {
8428 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8430 U->getOperand(0) == Vec &&
8432 U->getConstantOperandVal(1) == 1) {
8434 if (OtherRound.
getOpcode() ==
N->getOpcode() &&
8438 if (
N->isStrictFPOpcode()) {
8443 {MVT::v4f32, MVT::Other}, {Chain, Vec});
8448 DCI.AddToWorklist(VRound.
getNode());
8452 DCI.AddToWorklist(Extract1.
getNode());
8461 N->getVTList(), Extract0, Chain);
8470SDValue SystemZTargetLowering::combineFP_EXTEND(
8471 SDNode *
N, DAGCombinerInfo &DCI)
const {
8473 if (!Subtarget.hasVector())
8482 unsigned OpNo =
N->isStrictFPOpcode() ? 1 : 0;
8485 if (
N->getValueType(0) == MVT::f64 && Op0.
hasOneUse() &&
8491 for (
auto *U : Vec->
users()) {
8492 if (U != Op0.
getNode() &&
U->hasOneUse() &&
8494 U->getOperand(0) == Vec &&
8496 U->getConstantOperandVal(1) == 2) {
8498 if (OtherExtend.
getOpcode() ==
N->getOpcode() &&
8502 if (
N->isStrictFPOpcode()) {
8507 {MVT::v2f64, MVT::Other}, {Chain, Vec});
8512 DCI.AddToWorklist(VExtend.
getNode());
8516 DCI.AddToWorklist(Extract1.
getNode());
8525 N->getVTList(), Extract0, Chain);
8534SDValue SystemZTargetLowering::combineINT_TO_FP(
8535 SDNode *
N, DAGCombinerInfo &DCI)
const {
8540 unsigned Opcode =
N->getOpcode();
8541 EVT OutVT =
N->getValueType(0);
8545 unsigned InScalarBits =
Op->getValueType(0).getScalarSizeInBits();
8551 if (OutLLVMTy->
isVectorTy() && OutScalarBits > InScalarBits &&
8552 OutScalarBits <= 64) {
8553 unsigned NumElts = cast<FixedVectorType>(OutLLVMTy)->getNumElements();
8556 unsigned ExtOpcode =
8564SDValue SystemZTargetLowering::combineFCOPYSIGN(
8565 SDNode *
N, DAGCombinerInfo &DCI)
const {
8567 EVT VT =
N->getValueType(0);
8580SDValue SystemZTargetLowering::combineBSWAP(
8581 SDNode *
N, DAGCombinerInfo &DCI)
const {
8585 N->getOperand(0).hasOneUse() &&
8586 canLoadStoreByteSwapped(
N->getValueType(0))) {
8595 EVT LoadVT =
N->getValueType(0);
8596 if (LoadVT == MVT::i16)
8601 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
8605 if (
N->getValueType(0) == MVT::i16)
8610 DCI.CombineTo(
N, ResVal);
8614 DCI.CombineTo(
Load.getNode(), ResVal, BSLoad.
getValue(1));
8623 Op.getValueType().isVector() &&
8624 Op.getOperand(0).getValueType().isVector() &&
8625 Op.getValueType().getVectorNumElements() ==
8626 Op.getOperand(0).getValueType().getVectorNumElements())
8627 Op =
Op.getOperand(0);
8639 (canLoadStoreByteSwapped(
N->getValueType(0)) &&
8641 EVT VecVT =
N->getValueType(0);
8642 EVT EltVT =
N->getValueType(0).getVectorElementType();
8645 DCI.AddToWorklist(Vec.
getNode());
8649 DCI.AddToWorklist(Elt.
getNode());
8652 DCI.AddToWorklist(Vec.
getNode());
8654 DCI.AddToWorklist(Elt.
getNode());
8662 if (SV &&
Op.hasOneUse()) {
8670 EVT VecVT =
N->getValueType(0);
8673 DCI.AddToWorklist(Op0.
getNode());
8677 DCI.AddToWorklist(Op1.
getNode());
8680 DCI.AddToWorklist(Op0.
getNode());
8682 DCI.AddToWorklist(Op1.
getNode());
8690SDValue SystemZTargetLowering::combineSETCC(
8691 SDNode *
N, DAGCombinerInfo &DCI)
const {
8693 const ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
8698 EVT VT =
N->getValueType(0);
8708 Src.getValueType().isFixedLengthVector() &&
8709 Src.getValueType().getScalarType() == MVT::i1) {
8710 EVT CmpVT = Src.getOperand(0).getValueType();
8740 auto *CompareRHS = dyn_cast<ConstantSDNode>(ICmp->getOperand(1));
8747 bool Invert =
false;
8754 auto *TrueVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(0));
8757 auto *FalseVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(1));
8760 if (CompareRHS->getAPIntValue() == FalseVal->getAPIntValue())
8762 else if (CompareRHS->getAPIntValue() != TrueVal->getAPIntValue())
8766 auto *NewCCValid = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(2));
8767 auto *NewCCMask = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(3));
8768 if (!NewCCValid || !NewCCMask)
8770 CCValid = NewCCValid->getZExtValue();
8771 CCMask = NewCCMask->getZExtValue();
8781 if (CompareLHS->getOpcode() ==
ISD::SRA) {
8782 auto *SRACount = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(1));
8783 if (!SRACount || SRACount->getZExtValue() != 30)
8785 auto *SHL = CompareLHS->getOperand(0).getNode();
8788 auto *SHLCount = dyn_cast<ConstantSDNode>(SHL->getOperand(1));
8791 auto *IPM = SHL->getOperand(0).getNode();
8796 if (!CompareLHS->hasOneUse())
8799 if (CompareRHS->getZExtValue() != 0)
8806 CCReg = IPM->getOperand(0);
8813SDValue SystemZTargetLowering::combineBR_CCMASK(
8814 SDNode *
N, DAGCombinerInfo &DCI)
const {
8818 auto *CCValid = dyn_cast<ConstantSDNode>(
N->getOperand(1));
8819 auto *CCMask = dyn_cast<ConstantSDNode>(
N->getOperand(2));
8820 if (!CCValid || !CCMask)
8823 int CCValidVal = CCValid->getZExtValue();
8824 int CCMaskVal = CCMask->getZExtValue();
8833 N->getOperand(3), CCReg);
8837SDValue SystemZTargetLowering::combineSELECT_CCMASK(
8838 SDNode *
N, DAGCombinerInfo &DCI)
const {
8842 auto *CCValid = dyn_cast<ConstantSDNode>(
N->getOperand(2));
8843 auto *CCMask = dyn_cast<ConstantSDNode>(
N->getOperand(3));
8844 if (!CCValid || !CCMask)
8847 int CCValidVal = CCValid->getZExtValue();
8848 int CCMaskVal = CCMask->getZExtValue();
8853 N->getOperand(0),
N->getOperand(1),
8861SDValue SystemZTargetLowering::combineGET_CCMASK(
8862 SDNode *
N, DAGCombinerInfo &DCI)
const {
8865 auto *CCValid = dyn_cast<ConstantSDNode>(
N->getOperand(1));
8866 auto *CCMask = dyn_cast<ConstantSDNode>(
N->getOperand(2));
8867 if (!CCValid || !CCMask)
8869 int CCValidVal = CCValid->getZExtValue();
8870 int CCMaskVal = CCMask->getZExtValue();
8878 auto *SelectCCValid = dyn_cast<ConstantSDNode>(
Select->getOperand(2));
8879 auto *SelectCCMask = dyn_cast<ConstantSDNode>(
Select->getOperand(3));
8880 if (!SelectCCValid || !SelectCCMask)
8882 int SelectCCValidVal = SelectCCValid->getZExtValue();
8883 int SelectCCMaskVal = SelectCCMask->getZExtValue();
8885 auto *
TrueVal = dyn_cast<ConstantSDNode>(
Select->getOperand(0));
8886 auto *
FalseVal = dyn_cast<ConstantSDNode>(
Select->getOperand(1));
8887 if (!TrueVal || !FalseVal)
8891 else if (
TrueVal->getZExtValue() == 0 &&
FalseVal->getZExtValue() == 1)
8892 SelectCCMaskVal ^= SelectCCValidVal;
8896 if (SelectCCValidVal & ~CCValidVal)
8898 if (SelectCCMaskVal != (CCMaskVal & SelectCCValidVal))
8901 return Select->getOperand(4);
8904SDValue SystemZTargetLowering::combineIntDIVREM(
8905 SDNode *
N, DAGCombinerInfo &DCI)
const {
8907 EVT VT =
N->getValueType(0);
8924SDValue SystemZTargetLowering::combineShiftToMulAddHigh(
8925 SDNode *
N, DAGCombinerInfo &DCI)
const {
8930 "SRL or SRA node is required here!");
8932 if (!Subtarget.hasVector())
8942 SDValue ShiftOperand =
N->getOperand(0);
8962 if (!IsSignExt && !IsZeroExt)
8970 unsigned ActiveBits = IsSignExt
8971 ?
Constant->getAPIntValue().getSignificantBits()
8972 :
Constant->getAPIntValue().getActiveBits();
8973 if (ActiveBits > NarrowVTSize)
8989 unsigned ActiveBits = IsSignExt
8990 ?
Constant->getAPIntValue().getSignificantBits()
8991 :
Constant->getAPIntValue().getActiveBits();
8992 if (ActiveBits > NarrowVTSize)
9009 "Cannot have a multiply node with two different operand types.");
9011 "Cannot have an add node with two different operand types.");
9022 if (ShiftAmt != NarrowVTSize)
9026 if (!(NarrowVT == MVT::v16i8 || NarrowVT == MVT::v8i16 ||
9027 NarrowVT == MVT::v4i32 ||
9028 (Subtarget.hasVectorEnhancements3() &&
9029 (NarrowVT == MVT::v2i64 || NarrowVT == MVT::i128))))
9035 MulhRightOp, MulhAddOp);
9036 bool IsSigned =
N->getOpcode() ==
ISD::SRA;
9047 EVT VT =
Op.getValueType();
9056 Op =
Op.getOperand(0);
9057 if (
Op.getValueType().getVectorNumElements() == 2 * NumElts &&
9061 bool CanUseEven =
true, CanUseOdd =
true;
9062 for (
unsigned Elt = 0; Elt < NumElts; Elt++) {
9063 if (ShuffleMask[Elt] == -1)
9065 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt)
9067 if (
unsigned(ShuffleMask[Elt]) != 2 * Elt + 1)
9070 Op =
Op.getOperand(0);
9080 if (VT == MVT::i128 && Subtarget.hasVectorEnhancements3() &&
9084 Op =
Op.getOperand(0);
9086 Op.getOperand(0).getValueType() == MVT::v2i64 &&
9088 unsigned Elem =
Op.getConstantOperandVal(1);
9089 Op =
Op.getOperand(0);
9100SDValue SystemZTargetLowering::combineMUL(
9101 SDNode *
N, DAGCombinerInfo &DCI)
const {
9109 if (OpcodeCand0 && OpcodeCand0 == OpcodeCand1)
9110 return DAG.
getNode(OpcodeCand0,
SDLoc(
N),
N->getValueType(0), Op0, Op1);
9115SDValue SystemZTargetLowering::combineINTRINSIC(
9116 SDNode *
N, DAGCombinerInfo &DCI)
const {
9119 unsigned Id =
N->getConstantOperandVal(1);
9123 case Intrinsic::s390_vll:
9124 case Intrinsic::s390_vlrl:
9125 if (
auto *
C = dyn_cast<ConstantSDNode>(
N->getOperand(2)))
9126 if (
C->getZExtValue() >= 15)
9131 case Intrinsic::s390_vstl:
9132 case Intrinsic::s390_vstrl:
9133 if (
auto *
C = dyn_cast<ConstantSDNode>(
N->getOperand(3)))
9134 if (
C->getZExtValue() >= 15)
9145 return N->getOperand(0);
9151 switch(
N->getOpcode()) {
9176 case ISD::SRA:
return combineShiftToMulAddHigh(
N, DCI);
9177 case ISD::MUL:
return combineMUL(
N, DCI);
9181 case ISD::UREM:
return combineIntDIVREM(
N, DCI);
9193 EVT VT =
Op.getValueType();
9196 unsigned Opcode =
Op.getOpcode();
9198 unsigned Id =
Op.getConstantOperandVal(0);
9200 case Intrinsic::s390_vpksh:
9201 case Intrinsic::s390_vpksf:
9202 case Intrinsic::s390_vpksg:
9203 case Intrinsic::s390_vpkshs:
9204 case Intrinsic::s390_vpksfs:
9205 case Intrinsic::s390_vpksgs:
9206 case Intrinsic::s390_vpklsh:
9207 case Intrinsic::s390_vpklsf:
9208 case Intrinsic::s390_vpklsg:
9209 case Intrinsic::s390_vpklshs:
9210 case Intrinsic::s390_vpklsfs:
9211 case Intrinsic::s390_vpklsgs:
9213 SrcDemE = DemandedElts;
9216 SrcDemE = SrcDemE.
trunc(NumElts / 2);
9219 case Intrinsic::s390_vuphb:
9220 case Intrinsic::s390_vuphh:
9221 case Intrinsic::s390_vuphf:
9222 case Intrinsic::s390_vuplhb:
9223 case Intrinsic::s390_vuplhh:
9224 case Intrinsic::s390_vuplhf:
9225 SrcDemE =
APInt(NumElts * 2, 0);
9228 case Intrinsic::s390_vuplb:
9229 case Intrinsic::s390_vuplhw:
9230 case Intrinsic::s390_vuplf:
9231 case Intrinsic::s390_vupllb:
9232 case Intrinsic::s390_vupllh:
9233 case Intrinsic::s390_vupllf:
9234 SrcDemE =
APInt(NumElts * 2, 0);
9237 case Intrinsic::s390_vpdi: {
9239 SrcDemE =
APInt(NumElts, 0);
9240 if (!DemandedElts[OpNo - 1])
9242 unsigned Mask =
Op.getConstantOperandVal(3);
9243 unsigned MaskBit = ((OpNo - 1) ? 1 : 4);
9245 SrcDemE.
setBit((Mask & MaskBit)? 1 : 0);
9248 case Intrinsic::s390_vsldb: {
9250 assert(VT == MVT::v16i8 &&
"Unexpected type.");
9251 unsigned FirstIdx =
Op.getConstantOperandVal(3);
9252 assert (FirstIdx > 0 && FirstIdx < 16 &&
"Unused operand.");
9253 unsigned NumSrc0Els = 16 - FirstIdx;
9254 SrcDemE =
APInt(NumElts, 0);
9256 APInt DemEls = DemandedElts.
trunc(NumSrc0Els);
9259 APInt DemEls = DemandedElts.
lshr(NumSrc0Els);
9264 case Intrinsic::s390_vperm:
9275 SrcDemE =
APInt(1, 1);
9278 SrcDemE = DemandedElts;
9289 const APInt &DemandedElts,
9304 const APInt &DemandedElts,
9306 unsigned Depth)
const {
9310 unsigned Tmp0, Tmp1;
9315 EVT VT =
Op.getValueType();
9316 if (
Op.getResNo() != 0 || VT == MVT::Untyped)
9319 "KnownBits does not match VT in bitwidth");
9322 "DemandedElts does not match VT number of elements");
9324 unsigned Opcode =
Op.getOpcode();
9326 bool IsLogical =
false;
9327 unsigned Id =
Op.getConstantOperandVal(0);
9329 case Intrinsic::s390_vpksh:
9330 case Intrinsic::s390_vpksf:
9331 case Intrinsic::s390_vpksg:
9332 case Intrinsic::s390_vpkshs:
9333 case Intrinsic::s390_vpksfs:
9334 case Intrinsic::s390_vpksgs:
9335 case Intrinsic::s390_vpklsh:
9336 case Intrinsic::s390_vpklsf:
9337 case Intrinsic::s390_vpklsg:
9338 case Intrinsic::s390_vpklshs:
9339 case Intrinsic::s390_vpklsfs:
9340 case Intrinsic::s390_vpklsgs:
9341 case Intrinsic::s390_vpdi:
9342 case Intrinsic::s390_vsldb:
9343 case Intrinsic::s390_vperm:
9346 case Intrinsic::s390_vuplhb:
9347 case Intrinsic::s390_vuplhh:
9348 case Intrinsic::s390_vuplhf:
9349 case Intrinsic::s390_vupllb:
9350 case Intrinsic::s390_vupllh:
9351 case Intrinsic::s390_vupllf:
9354 case Intrinsic::s390_vuphb:
9355 case Intrinsic::s390_vuphh:
9356 case Intrinsic::s390_vuphf:
9357 case Intrinsic::s390_vuplb:
9358 case Intrinsic::s390_vuplhw:
9359 case Intrinsic::s390_vuplf: {
9401 if (
LHS == 1)
return 1;
9404 if (
RHS == 1)
return 1;
9405 unsigned Common = std::min(
LHS,
RHS);
9406 unsigned SrcBitWidth =
Op.getOperand(OpNo).getScalarValueSizeInBits();
9407 EVT VT =
Op.getValueType();
9409 if (SrcBitWidth > VTBits) {
9410 unsigned SrcExtraBits = SrcBitWidth - VTBits;
9411 if (Common > SrcExtraBits)
9412 return (Common - SrcExtraBits);
9415 assert (SrcBitWidth == VTBits &&
"Expected operands of same bitwidth.");
9422 unsigned Depth)
const {
9423 if (
Op.getResNo() != 0)
9425 unsigned Opcode =
Op.getOpcode();
9427 unsigned Id =
Op.getConstantOperandVal(0);
9429 case Intrinsic::s390_vpksh:
9430 case Intrinsic::s390_vpksf:
9431 case Intrinsic::s390_vpksg:
9432 case Intrinsic::s390_vpkshs:
9433 case Intrinsic::s390_vpksfs:
9434 case Intrinsic::s390_vpksgs:
9435 case Intrinsic::s390_vpklsh:
9436 case Intrinsic::s390_vpklsf:
9437 case Intrinsic::s390_vpklsg:
9438 case Intrinsic::s390_vpklshs:
9439 case Intrinsic::s390_vpklsfs:
9440 case Intrinsic::s390_vpklsgs:
9441 case Intrinsic::s390_vpdi:
9442 case Intrinsic::s390_vsldb:
9443 case Intrinsic::s390_vperm:
9445 case Intrinsic::s390_vuphb:
9446 case Intrinsic::s390_vuphh:
9447 case Intrinsic::s390_vuphf:
9448 case Intrinsic::s390_vuplb:
9449 case Intrinsic::s390_vuplhw:
9450 case Intrinsic::s390_vuplf: {
9454 EVT VT =
Op.getValueType();
9478 switch (
Op->getOpcode()) {
9491 "Unexpected stack alignment");
9494 unsigned StackProbeSize =
9497 StackProbeSize &= ~(StackAlign - 1);
9498 return StackProbeSize ? StackProbeSize : StackAlign;
9515 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9521 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
9537 if (
MI.readsRegister(SystemZ::CC,
nullptr))
9539 if (
MI.definesRegister(SystemZ::CC,
nullptr))
9547 if (Succ->isLiveIn(SystemZ::CC))
9558 switch (
MI.getOpcode()) {
9559 case SystemZ::Select32:
9560 case SystemZ::Select64:
9561 case SystemZ::Select128:
9562 case SystemZ::SelectF32:
9563 case SystemZ::SelectF64:
9564 case SystemZ::SelectF128:
9565 case SystemZ::SelectVR32:
9566 case SystemZ::SelectVR64:
9567 case SystemZ::SelectVR128:
9599 for (
auto *
MI : Selects) {
9600 Register DestReg =
MI->getOperand(0).getReg();
9601 Register TrueReg =
MI->getOperand(1).getReg();
9602 Register FalseReg =
MI->getOperand(2).getReg();
9607 if (
MI->getOperand(4).getImm() == (CCValid ^ CCMask))
9610 if (
auto It = RegRewriteTable.
find(TrueReg); It != RegRewriteTable.
end())
9611 TrueReg = It->second.first;
9613 if (
auto It = RegRewriteTable.
find(FalseReg); It != RegRewriteTable.
end())
9614 FalseReg = It->second.second;
9617 BuildMI(*SinkMBB, SinkInsertionPoint,
DL,
TII->get(SystemZ::PHI), DestReg)
9622 RegRewriteTable[DestReg] = std::make_pair(TrueReg, FalseReg);
9634 assert(TFL->hasReservedCallFrame(MF) &&
9635 "ADJSTACKDOWN and ADJSTACKUP should be no-ops");
9640 uint32_t NumBytes =
MI.getOperand(0).getImm();
9645 MI.eraseFromParent();
9656 unsigned CCValid =
MI.getOperand(3).getImm();
9657 unsigned CCMask =
MI.getOperand(4).getImm();
9669 assert(NextMI.getOperand(3).getImm() == CCValid &&
9670 "Bad CCValid operands since CC was not redefined.");
9671 if (NextMI.getOperand(4).getImm() == CCMask ||
9672 NextMI.getOperand(4).getImm() == (CCValid ^ CCMask)) {
9678 if (NextMI.definesRegister(SystemZ::CC,
nullptr) ||
9679 NextMI.usesCustomInsertionHook())
9682 for (
auto *SelMI : Selects)
9683 if (NextMI.readsVirtualRegister(SelMI->getOperand(0).getReg())) {
9687 if (NextMI.isDebugInstr()) {
9689 assert(NextMI.isDebugValue() &&
"Unhandled debug opcode.");
9692 }
else if (
User || ++Count > 20)
9697 bool CCKilled = (LastMI->
killsRegister(SystemZ::CC,
nullptr) ||
9729 for (
auto *SelMI : Selects)
9730 SelMI->eraseFromParent();
9733 for (
auto *DbgMI : DbgValues)
9734 MBB->
splice(InsertPos, StartMBB, DbgMI);
9745 unsigned StoreOpcode,
9746 unsigned STOCOpcode,
9747 bool Invert)
const {
9752 int64_t Disp =
MI.getOperand(2).getImm();
9753 Register IndexReg =
MI.getOperand(3).getReg();
9754 unsigned CCValid =
MI.getOperand(4).getImm();
9755 unsigned CCMask =
MI.getOperand(5).getImm();
9758 StoreOpcode =
TII->getOpcodeForOffset(StoreOpcode, Disp);
9763 for (
auto *
I :
MI.memoperands())
9772 if (STOCOpcode && !IndexReg && Subtarget.hasLoadStoreOnCond()) {
9784 MI.eraseFromParent();
9798 if (!
MI.killsRegister(SystemZ::CC,
nullptr) &&
9825 MI.eraseFromParent();
9861 int HiOpcode =
Unsigned? SystemZ::VECLG : SystemZ::VECG;
9880 Register Temp =
MRI.createVirtualRegister(&SystemZ::VR128BitRegClass);
9888 MI.eraseFromParent();
9899 bool Invert)
const {
9908 int64_t Disp =
MI.getOperand(2).getImm();
9910 Register BitShift =
MI.getOperand(4).getReg();
9911 Register NegBitShift =
MI.getOperand(5).getReg();
9912 unsigned BitSize =
MI.getOperand(6).getImm();
9916 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
9917 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
9918 assert(LOpcode && CSOpcode &&
"Displacement out of range");
9921 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
9922 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
9923 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
9924 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
9925 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
9956 Register Tmp =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
9961 }
else if (BinOpcode)
9984 MI.eraseFromParent();
9995 unsigned KeepOldMask)
const {
10003 int64_t Disp =
MI.getOperand(2).getImm();
10005 Register BitShift =
MI.getOperand(4).getReg();
10006 Register NegBitShift =
MI.getOperand(5).getReg();
10007 unsigned BitSize =
MI.getOperand(6).getImm();
10011 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10012 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10013 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10016 Register OrigVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10017 Register OldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10018 Register NewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10019 Register RotatedOldVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10020 Register RotatedAltVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10021 Register RotatedNewVal =
MRI.createVirtualRegister(&SystemZ::GR32BitRegClass);
10088 MI.eraseFromParent();
10104 int64_t Disp =
MI.getOperand(2).getImm();
10105 Register CmpVal =
MI.getOperand(3).getReg();
10106 Register OrigSwapVal =
MI.getOperand(4).getReg();
10107 Register BitShift =
MI.getOperand(5).getReg();
10108 Register NegBitShift =
MI.getOperand(6).getReg();
10109 int64_t BitSize =
MI.getOperand(7).getImm();
10115 unsigned LOpcode =
TII->getOpcodeForOffset(SystemZ::L, Disp);
10116 unsigned CSOpcode =
TII->getOpcodeForOffset(SystemZ::CS, Disp);
10117 unsigned ZExtOpcode = BitSize == 8 ? SystemZ::LLCR : SystemZ::LLHR;
10118 assert(LOpcode && CSOpcode &&
"Displacement out of range");
10121 Register OrigOldVal =
MRI.createVirtualRegister(RC);
10123 Register SwapVal =
MRI.createVirtualRegister(RC);
10124 Register StoreVal =
MRI.createVirtualRegister(RC);
10125 Register OldValRot =
MRI.createVirtualRegister(RC);
10126 Register RetryOldVal =
MRI.createVirtualRegister(RC);
10127 Register RetrySwapVal =
MRI.createVirtualRegister(RC);
10202 if (!
MI.registerDefIsDead(SystemZ::CC,
nullptr))
10205 MI.eraseFromParent();
10218 .
add(
MI.getOperand(1))
10219 .
addImm(SystemZ::subreg_h64)
10220 .
add(
MI.getOperand(2))
10221 .
addImm(SystemZ::subreg_l64);
10222 MI.eraseFromParent();
10231 bool ClearEven)
const {
10239 Register In128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10243 Register NewIn128 =
MRI.createVirtualRegister(&SystemZ::GR128BitRegClass);
10244 Register Zero64 =
MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10255 MI.eraseFromParent();
10262 unsigned Opcode,
bool IsMemset)
const {
10269 uint64_t DestDisp =
MI.getOperand(1).getImm();
10275 if (!isUInt<12>(Disp)) {
10276 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10277 unsigned Opcode =
TII->getOpcodeForOffset(SystemZ::LA, Disp);
10287 SrcDisp =
MI.getOperand(3).getImm();
10289 SrcBase = DestBase;
10290 SrcDisp = DestDisp++;
10291 foldDisplIfNeeded(DestBase, DestDisp);
10295 bool IsImmForm = LengthMO.
isImm();
10296 bool IsRegForm = !IsImmForm;
10303 unsigned Length) ->
void {
10307 if (ByteMO.
isImm())
10322 bool NeedsLoop =
false;
10324 Register LenAdjReg = SystemZ::NoRegister;
10326 ImmLength = LengthMO.
getImm();
10327 ImmLength += IsMemset ? 2 : 1;
10328 if (ImmLength == 0) {
10329 MI.eraseFromParent();
10332 if (Opcode == SystemZ::CLC) {
10333 if (ImmLength > 3 * 256)
10343 }
else if (ImmLength > 6 * 256)
10351 LenAdjReg = LengthMO.
getReg();
10357 (Opcode == SystemZ::CLC && (ImmLength > 256 || NeedsLoop)
10363 MRI.createVirtualRegister(&SystemZ::GR64BitRegClass);
10365 TII->loadImmediate(*
MBB,
MI, StartCountReg, ImmLength / 256);
10376 Register Reg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10380 if (DestBase.
isReg() && DestBase.
getReg() == SystemZ::NoRegister)
10381 DestBase = loadZeroAddress();
10382 if (SrcBase.
isReg() && SrcBase.
getReg() == SystemZ::NoRegister)
10383 SrcBase = HaveSingleBase ? DestBase : loadZeroAddress();
10393 (HaveSingleBase ? StartSrcReg :
forceReg(
MI, DestBase,
TII));
10396 Register ThisSrcReg =
MRI.createVirtualRegister(RC);
10398 (HaveSingleBase ? ThisSrcReg :
MRI.createVirtualRegister(RC));
10399 Register NextSrcReg =
MRI.createVirtualRegister(RC);
10401 (HaveSingleBase ? NextSrcReg :
MRI.createVirtualRegister(RC));
10402 RC = &SystemZ::GR64BitRegClass;
10403 Register ThisCountReg =
MRI.createVirtualRegister(RC);
10404 Register NextCountReg =
MRI.createVirtualRegister(RC);
10430 MBB = MemsetOneCheckMBB;
10441 MBB = MemsetOneMBB;
10473 if (EndMBB && !ImmLength)
10495 if (!HaveSingleBase)
10502 if (Opcode == SystemZ::MVC)
10529 if (!HaveSingleBase)
10551 Register RemSrcReg =
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10552 Register RemDestReg = HaveSingleBase ? RemSrcReg
10553 :
MRI.createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10557 if (!HaveSingleBase)
10573 if (Opcode != SystemZ::MVC) {
10583 while (ImmLength > 0) {
10587 foldDisplIfNeeded(DestBase, DestDisp);
10588 foldDisplIfNeeded(SrcBase, SrcDisp);
10589 insertMemMemOp(
MBB,
MI, DestBase, DestDisp, SrcBase, SrcDisp, ThisLength);
10590 DestDisp += ThisLength;
10591 SrcDisp += ThisLength;
10592 ImmLength -= ThisLength;
10595 if (EndMBB && ImmLength > 0) {
10611 MI.eraseFromParent();
10624 uint64_t End1Reg =
MI.getOperand(0).getReg();
10625 uint64_t Start1Reg =
MI.getOperand(1).getReg();
10626 uint64_t Start2Reg =
MI.getOperand(2).getReg();
10627 uint64_t CharReg =
MI.getOperand(3).getReg();
10630 uint64_t This1Reg =
MRI.createVirtualRegister(RC);
10631 uint64_t This2Reg =
MRI.createVirtualRegister(RC);
10632 uint64_t End2Reg =
MRI.createVirtualRegister(RC);
10670 MI.eraseFromParent();
10677 bool NoFloat)
const {
10683 MI.setDesc(
TII->get(Opcode));
10687 uint64_t Control =
MI.getOperand(2).getImm();
10688 static const unsigned GPRControlBit[16] = {
10689 0x8000, 0x8000, 0x4000, 0x4000, 0x2000, 0x2000, 0x1000, 0x1000,
10690 0x0800, 0x0800, 0x0400, 0x0400, 0x0200, 0x0200, 0x0100, 0x0100
10692 Control |= GPRControlBit[15];
10693 if (TFI->
hasFP(MF))
10694 Control |= GPRControlBit[11];
10695 MI.getOperand(2).setImm(Control);
10698 for (
int I = 0;
I < 16;
I++) {
10699 if ((Control & GPRControlBit[
I]) == 0) {
10706 if (!NoFloat && (Control & 4) != 0) {
10707 if (Subtarget.hasVector()) {
10728 Register SrcReg =
MI.getOperand(0).getReg();
10732 Register DstReg =
MRI->createVirtualRegister(RC);
10739 MI.eraseFromParent();
10751 Register DstReg =
MI.getOperand(0).getReg();
10752 Register SizeReg =
MI.getOperand(2).getReg();
10764 Register PHIReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10765 Register IncReg =
MRI->createVirtualRegister(&SystemZ::ADDR64BitRegClass);
10830 MI.eraseFromParent();
10834SDValue SystemZTargetLowering::
10845 switch (
MI.getOpcode()) {
10846 case SystemZ::ADJCALLSTACKDOWN:
10847 case SystemZ::ADJCALLSTACKUP:
10848 return emitAdjCallStack(
MI,
MBB);
10850 case SystemZ::Select32:
10851 case SystemZ::Select64:
10852 case SystemZ::Select128:
10853 case SystemZ::SelectF32:
10854 case SystemZ::SelectF64:
10855 case SystemZ::SelectF128:
10856 case SystemZ::SelectVR32:
10857 case SystemZ::SelectVR64:
10858 case SystemZ::SelectVR128:
10859 return emitSelect(
MI,
MBB);
10861 case SystemZ::CondStore8Mux:
10862 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
false);
10863 case SystemZ::CondStore8MuxInv:
10864 return emitCondStore(
MI,
MBB, SystemZ::STCMux, 0,
true);
10865 case SystemZ::CondStore16Mux:
10866 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
false);
10867 case SystemZ::CondStore16MuxInv:
10868 return emitCondStore(
MI,
MBB, SystemZ::STHMux, 0,
true);
10869 case SystemZ::CondStore32Mux:
10870 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
false);
10871 case SystemZ::CondStore32MuxInv:
10872 return emitCondStore(
MI,
MBB, SystemZ::STMux, SystemZ::STOCMux,
true);
10873 case SystemZ::CondStore8:
10874 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
false);
10875 case SystemZ::CondStore8Inv:
10876 return emitCondStore(
MI,
MBB, SystemZ::STC, 0,
true);
10877 case SystemZ::CondStore16:
10878 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
false);
10879 case SystemZ::CondStore16Inv:
10880 return emitCondStore(
MI,
MBB, SystemZ::STH, 0,
true);
10881 case SystemZ::CondStore32:
10882 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
false);
10883 case SystemZ::CondStore32Inv:
10884 return emitCondStore(
MI,
MBB, SystemZ::ST, SystemZ::STOC,
true);
10885 case SystemZ::CondStore64:
10886 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
false);
10887 case SystemZ::CondStore64Inv:
10888 return emitCondStore(
MI,
MBB, SystemZ::STG, SystemZ::STOCG,
true);
10889 case SystemZ::CondStoreF32:
10890 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
false);
10891 case SystemZ::CondStoreF32Inv:
10892 return emitCondStore(
MI,
MBB, SystemZ::STE, 0,
true);
10893 case SystemZ::CondStoreF64:
10894 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
false);
10895 case SystemZ::CondStoreF64Inv:
10896 return emitCondStore(
MI,
MBB, SystemZ::STD, 0,
true);
10898 case SystemZ::SCmp128Hi:
10899 return emitICmp128Hi(
MI,
MBB,
false);
10900 case SystemZ::UCmp128Hi:
10901 return emitICmp128Hi(
MI,
MBB,
true);
10903 case SystemZ::PAIR128:
10904 return emitPair128(
MI,
MBB);
10905 case SystemZ::AEXT128:
10906 return emitExt128(
MI,
MBB,
false);
10907 case SystemZ::ZEXT128:
10908 return emitExt128(
MI,
MBB,
true);
10910 case SystemZ::ATOMIC_SWAPW:
10911 return emitAtomicLoadBinary(
MI,
MBB, 0);
10913 case SystemZ::ATOMIC_LOADW_AR:
10914 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AR);
10915 case SystemZ::ATOMIC_LOADW_AFI:
10916 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::AFI);
10918 case SystemZ::ATOMIC_LOADW_SR:
10919 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::SR);
10921 case SystemZ::ATOMIC_LOADW_NR:
10922 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR);
10923 case SystemZ::ATOMIC_LOADW_NILH:
10924 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH);
10926 case SystemZ::ATOMIC_LOADW_OR:
10927 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OR);
10928 case SystemZ::ATOMIC_LOADW_OILH:
10929 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::OILH);
10931 case SystemZ::ATOMIC_LOADW_XR:
10932 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XR);
10933 case SystemZ::ATOMIC_LOADW_XILF:
10934 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::XILF);
10936 case SystemZ::ATOMIC_LOADW_NRi:
10937 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NR,
true);
10938 case SystemZ::ATOMIC_LOADW_NILHi:
10939 return emitAtomicLoadBinary(
MI,
MBB, SystemZ::NILH,
true);
10941 case SystemZ::ATOMIC_LOADW_MIN:
10943 case SystemZ::ATOMIC_LOADW_MAX:
10945 case SystemZ::ATOMIC_LOADW_UMIN:
10947 case SystemZ::ATOMIC_LOADW_UMAX:
10950 case SystemZ::ATOMIC_CMP_SWAPW:
10951 return emitAtomicCmpSwapW(
MI,
MBB);
10952 case SystemZ::MVCImm:
10953 case SystemZ::MVCReg:
10954 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC);
10955 case SystemZ::NCImm:
10956 return emitMemMemWrapper(
MI,
MBB, SystemZ::NC);
10957 case SystemZ::OCImm:
10958 return emitMemMemWrapper(
MI,
MBB, SystemZ::OC);
10959 case SystemZ::XCImm:
10960 case SystemZ::XCReg:
10961 return emitMemMemWrapper(
MI,
MBB, SystemZ::XC);
10962 case SystemZ::CLCImm:
10963 case SystemZ::CLCReg:
10964 return emitMemMemWrapper(
MI,
MBB, SystemZ::CLC);
10965 case SystemZ::MemsetImmImm:
10966 case SystemZ::MemsetImmReg:
10967 case SystemZ::MemsetRegImm:
10968 case SystemZ::MemsetRegReg:
10969 return emitMemMemWrapper(
MI,
MBB, SystemZ::MVC,
true);
10970 case SystemZ::CLSTLoop:
10971 return emitStringWrapper(
MI,
MBB, SystemZ::CLST);
10972 case SystemZ::MVSTLoop:
10973 return emitStringWrapper(
MI,
MBB, SystemZ::MVST);
10974 case SystemZ::SRSTLoop:
10975 return emitStringWrapper(
MI,
MBB, SystemZ::SRST);
10976 case SystemZ::TBEGIN:
10977 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
false);
10978 case SystemZ::TBEGIN_nofloat:
10979 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGIN,
true);
10980 case SystemZ::TBEGINC:
10981 return emitTransactionBegin(
MI,
MBB, SystemZ::TBEGINC,
true);
10982 case SystemZ::LTEBRCompare_Pseudo:
10983 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTEBR);
10984 case SystemZ::LTDBRCompare_Pseudo:
10985 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTDBR);
10986 case SystemZ::LTXBRCompare_Pseudo:
10987 return emitLoadAndTestCmp0(
MI,
MBB, SystemZ::LTXBR);
10989 case SystemZ::PROBED_ALLOCA:
10990 return emitProbedAlloca(
MI,
MBB);
10991 case SystemZ::EH_SjLj_SetJmp:
10993 case SystemZ::EH_SjLj_LongJmp:
10996 case TargetOpcode::STACKMAP:
10997 case TargetOpcode::PATCHPOINT:
11008SystemZTargetLowering::getRepRegClassFor(
MVT VT)
const {
11009 if (VT == MVT::Untyped)
11010 return &SystemZ::ADDR128BitRegClass;
11036 DAG.
getMachineNode(SystemZ::EFPC, dl, {MVT::i32, MVT::Other}, Chain), 0);
11056 EVT VT =
Op.getValueType();
11057 Op =
Op.getOperand(0);
11058 EVT OpVT =
Op.getValueType();
11060 assert(OpVT.
isVector() &&
"Operand type for VECREDUCE_ADD is not a vector.");
11092 if (Attrs.hasRetAttrs())
11094 OS << *
F->getReturnType() <<
" @" <<
F->getName() <<
"(";
11095 for (
unsigned I = 0, E = FT->getNumParams();
I != E; ++
I) {
11098 OS << *FT->getParamType(
I);
11100 for (
auto A : {Attribute::SExt, Attribute::ZExt, Attribute::NoExt})
11107bool SystemZTargetLowering::isInternal(
const Function *Fn)
const {
11108 std::map<const Function *, bool>::iterator Itr = IsInternalCache.find(Fn);
11109 if (Itr == IsInternalCache.end())
11110 Itr = IsInternalCache
11111 .insert(std::pair<const Function *, bool>(
11114 return Itr->second;
11117void SystemZTargetLowering::
11125 bool IsInternal =
false;
11126 const Function *CalleeFn =
nullptr;
11127 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(Callee))
11128 if ((CalleeFn = dyn_cast<Function>(
G->getGlobal())))
11129 IsInternal = isInternal(CalleeFn);
11130 if (!IsInternal && !verifyNarrowIntegerArgs(Outs)) {
11131 errs() <<
"ERROR: Missing extension attribute of passed "
11132 <<
"value in call to function:\n" <<
"Callee: ";
11133 if (CalleeFn !=
nullptr)
11137 errs() <<
"Caller: ";
11143void SystemZTargetLowering::
11151 if (!isInternal(
F) && !verifyNarrowIntegerArgs(Outs)) {
11152 errs() <<
"ERROR: Missing extension attribute of returned "
11153 <<
"value from function:\n";
11161bool SystemZTargetLowering::verifyNarrowIntegerArgs(
11172 for (
unsigned i = 0; i < Outs.
size(); ++i) {
11173 MVT VT = Outs[i].VT;
11177 "Unexpected integer argument VT.");
11178 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 Results
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
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)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static bool isSelectPseudo(MachineInstr &MI)
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static SDValue getI128Select(SelectionDAG &DAG, const SDLoc &DL, Comparison C, SDValue TrueOp, SDValue FalseOp)
static void adjustForTestUnderMask(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void printFunctionArgExts(const Function *F, raw_fd_ostream &OS)
static void adjustForLTGFR(Comparison &C)
static void adjustSubwordCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue joinDwords(SelectionDAG &DAG, const SDLoc &DL, SDValue Op0, SDValue Op1)
static cl::opt< bool > EnableIntArgExtCheck("argext-abi-check", cl::init(false), cl::desc("Verify that narrow int args are properly extended per the " "SystemZ ABI."))
static bool isOnlyUsedByStores(SDValue StoredVal, SelectionDAG &DAG)
static void lowerGR128Binary(SelectionDAG &DAG, const SDLoc &DL, EVT VT, unsigned Opcode, SDValue Op0, SDValue Op1, SDValue &Even, SDValue &Odd)
static void adjustForRedundantAnd(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static SDValue lowerAddrSpaceCast(SDValue Op, SelectionDAG &DAG)
static SDValue buildScalarToVector(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Value)
static SDValue lowerI128ToGR128(SelectionDAG &DAG, SDValue In)
static bool isSimpleShift(SDValue N, unsigned &ShiftVal)
static bool isI128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static bool chooseShuffleOpNos(int *OpNos, unsigned &OpNo0, unsigned &OpNo1)
static uint32_t findZeroVectorIdx(SDValue *Ops, unsigned Num)
static bool isVectorElementSwap(ArrayRef< int > M, EVT VT)
static void getCSAddressAndShifts(SDValue Addr, SelectionDAG &DAG, SDLoc DL, SDValue &AlignedAddr, SDValue &BitShift, SDValue &NegBitShift)
static bool isShlDoublePermute(const SmallVectorImpl< int > &Bytes, unsigned &StartIndex, unsigned &OpNo0, unsigned &OpNo1)
static SDValue getPermuteNode(SelectionDAG &DAG, const SDLoc &DL, const Permute &P, SDValue Op0, SDValue Op1)
static SDNode * emitIntrinsicWithCCAndChain(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static SDValue getCCResult(SelectionDAG &DAG, SDValue CCReg)
static bool isIntrinsicWithCCAndChain(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static void lowerMUL_LOHI32(SelectionDAG &DAG, const SDLoc &DL, unsigned Extend, SDValue Op0, SDValue Op1, SDValue &Hi, SDValue &Lo)
static bool isF128MovedToParts(LoadSDNode *LD, SDNode *&LoPart, SDNode *&HiPart)
static void createPHIsForSelects(SmallVector< MachineInstr *, 8 > &Selects, MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, MachineBasicBlock *SinkMBB)
static SDValue getGeneralPermuteNode(SelectionDAG &DAG, const SDLoc &DL, SDValue *Ops, const SmallVectorImpl< int > &Bytes)
static unsigned getVectorComparisonOrInvert(ISD::CondCode CC, CmpMode Mode, bool &Invert)
static unsigned CCMaskForCondCode(ISD::CondCode CC)
static void adjustICmpTruncate(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static void adjustForFNeg(Comparison &C)
static bool isScalarToVector(SDValue Op)
static SDValue emitSETCC(SelectionDAG &DAG, const SDLoc &DL, SDValue CCReg, unsigned CCValid, unsigned CCMask)
static bool matchPermute(const SmallVectorImpl< int > &Bytes, const Permute &P, unsigned &OpNo0, unsigned &OpNo1)
static bool isAddCarryChain(SDValue Carry)
static SDValue emitCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static MachineOperand earlyUseOperand(MachineOperand Op)
static bool canUseSiblingCall(const CCState &ArgCCInfo, SmallVectorImpl< CCValAssign > &ArgLocs, SmallVectorImpl< ISD::OutputArg > &Outs)
static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask)
static bool getzOSCalleeAndADA(SelectionDAG &DAG, SDValue &Callee, SDValue &ADA, SDLoc &DL, SDValue &Chain)
static SDValue convertToF16(SDValue Op, SelectionDAG &DAG)
static bool shouldSwapCmpOperands(const Comparison &C)
static bool isNaturalMemoryOperand(SDValue Op, unsigned ICmpType)
static SDValue getADAEntry(SelectionDAG &DAG, SDValue Val, SDLoc DL, unsigned Offset, bool LoadAdr=false)
static SDNode * emitIntrinsicWithCC(SelectionDAG &DAG, SDValue Op, unsigned Opcode)
static void adjustForSubtraction(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static bool getVPermMask(SDValue ShuffleOp, SmallVectorImpl< int > &Bytes)
static const Permute PermuteForms[]
static bool isI128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static bool isSubBorrowChain(SDValue Carry)
static void adjustICmp128(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
static APInt getDemandedSrcElements(SDValue Op, const APInt &DemandedElts, unsigned OpNo)
static SDValue getAbsolute(SelectionDAG &DAG, const SDLoc &DL, SDValue Op, bool IsNegative)
static unsigned computeNumSignBitsBinOp(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static SDValue expandBitCastI128ToF128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static SDValue tryBuildVectorShuffle(SelectionDAG &DAG, BuildVectorSDNode *BVN)
static SDValue convertFromF16(SDValue Op, SDLoc DL, SelectionDAG &DAG)
static unsigned getVectorComparison(ISD::CondCode CC, CmpMode Mode)
static SDValue lowerGR128ToI128(SelectionDAG &DAG, SDValue In)
static SDValue MergeInputChains(SDNode *N1, SDNode *N2)
static SDValue expandBitCastF128ToI128(SelectionDAG &DAG, SDValue Src, const SDLoc &SL)
static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask, uint64_t Mask, uint64_t CmpVal, unsigned ICmpType)
static bool isIntrinsicWithCC(SDValue Op, unsigned &Opcode, unsigned &CCValid)
static SDValue expandV4F32ToV2F64(SelectionDAG &DAG, int Start, const SDLoc &DL, SDValue Op, SDValue Chain)
static Comparison getCmp(SelectionDAG &DAG, SDValue CmpOp0, SDValue CmpOp1, ISD::CondCode Cond, const SDLoc &DL, SDValue Chain=SDValue(), bool IsSignaling=false)
static bool checkCCKill(MachineInstr &MI, MachineBasicBlock *MBB)
static Register forceReg(MachineInstr &MI, MachineOperand &Base, const SystemZInstrInfo *TII)
static bool is32Bit(EVT VT)
static std::pair< unsigned, const TargetRegisterClass * > parseRegisterNumber(StringRef Constraint, const TargetRegisterClass *RC, const unsigned *Map, unsigned Size)
static unsigned detectEvenOddMultiplyOperand(const SelectionDAG &DAG, const SystemZSubtarget &Subtarget, SDValue &Op)
static bool matchDoublePermute(const SmallVectorImpl< int > &Bytes, const Permute &P, SmallVectorImpl< int > &Transform)
static Comparison getIntrinsicCmp(SelectionDAG &DAG, unsigned Opcode, SDValue Call, unsigned CCValid, uint64_t CC, ISD::CondCode Cond)
static bool isAbsolute(SDValue CmpOp, SDValue Pos, SDValue Neg)
static AddressingMode getLoadStoreAddrMode(bool HasVector, Type *Ty)
static SDValue buildMergeScalars(SelectionDAG &DAG, const SDLoc &DL, EVT VT, SDValue Op0, SDValue Op1)
static void computeKnownBitsBinOp(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth, unsigned OpNo)
static bool getShuffleInput(const SmallVectorImpl< int > &Bytes, unsigned Start, unsigned BytesPerElement, int &Base)
static AddressingMode supportedAddressingMode(Instruction *I, bool HasVector)
static bool isF128MovedFromParts(SDValue Val, SDValue &LoPart, SDValue &HiPart)
static void adjustZeroCmp(SelectionDAG &DAG, const SDLoc &DL, Comparison &C)
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),...
size_t size() const
size - Get the array size.
an instruction that atomically reads a memory location, combines it with another value,...
BinOp getOperation() const
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.
The address of a basic block.
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
LLVM_ABI bool isConstant() const
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
LLVM_ABI void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
LLVM_ABI void AnalyzeFormalArguments(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeFormalArguments - Analyze an array of argument values, incorporating info about the formals in...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
uint64_t getZExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false, bool IgnoreCastedDirectCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool hasLocalLinkage() const
bool hasPrivateLinkage() const
bool hasInternalLinkage() const
A wrapper class for inspecting calls to intrinsic functions.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
static auto integer_fixedlen_vector_valuetypes()
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
static MVT getVectorVT(MVT VT, unsigned NumElements)
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
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.
iterator_range< succ_iterator > successors()
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 '...
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.
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)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr kills the specified register.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
void setFlags(SDNodeFlags NewFlags)
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT, unsigned Opcode)
Convert Op, which must be of integer type, to the integer type VT, by either any/sign/zero-extending ...
LLVM_ABI SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS, unsigned DestAS)
Return an AddrSpaceCastSDNode.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getAtomicLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT MemVT, EVT VT, SDValue Chain, SDValue Ptr, MachineMemOperand *MMO)
LLVM_ABI SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offs=0, bool isT=false, unsigned TargetFlags=0)
LLVM_ABI bool isConstantIntBuildVectorOrConstantInt(SDValue N, bool AllowOpaques=true) const
Test whether the given value is a constant int or similar node.
LLVM_ABI SDValue UnrollVectorOp(SDNode *N, unsigned ResNE=0)
Utility function used by legalize and lowering to "unroll" a vector operation by splitting out the sc...
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getGLOBAL_OFFSET_TABLE(EVT VT)
Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, MachineMemOperand *MMO)
Gets a node for an atomic op, produces result (if relevant) and chain and takes 2 operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
LLVM_ABI SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand)
A convenience function for creating TargetInstrInfo::EXTRACT_SUBREG nodes.
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI std::pair< SDValue, SDValue > getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT)
Convert Op, which must be a STRICT operation of float type, to the float type VT, by either extending...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
LLVM_ABI SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of float type, to the float type VT, by either extending or rounding (by tr...
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
LLVM_ABI SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT, SDValue Operand, SDValue Subreg)
A convenience function for creating TargetInstrInfo::INSERT_SUBREG nodes.
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
ArrayRef< int > getMask() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
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
A SystemZ-specific constant pool value.
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
bool isPC32DBLSymbol(const GlobalValue *GV, CodeModel::Model CM) const
const TargetFrameLowering * getFrameLowering() const override
bool isTargetXPLINK64() const
SystemZCallingConventionRegisters * getSpecialRegisters() const
const SystemZRegisterInfo * getRegisterInfo() const override
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
MVT getRegisterTypeForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const override
Certain combinations of ABIs, Targets and features require that types are legal for some operations a...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
Returns the target specific optimal type for load and store operations as a result of memset,...
bool hasInlineStackProbe(const MachineFunction &MF) const override
Returns true if stack probing through inline assembly is requested.
bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes) const override
Determines the optimal series of memory ops to replace the memset / memcpy.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *BB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
AtomicExpansionKind shouldCastAtomicLoadInIR(LoadInst *LI) const override
Returns how the given (atomic) load should be cast by the IR-level AtomicExpand pass.
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &, EVT) const override
Return the ValueType of the result of SETCC operations.
bool allowTruncateForTailCall(Type *, Type *) const override
Return true if a truncation from FromTy to ToTy is permitted when deciding whether a call is in tail ...
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, const SmallVectorImpl< SDValue > &OutVals, const SDLoc &DL, SelectionDAG &DAG) const override
This hook must be implemented to lower outgoing return values, described by the Outs array,...
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool useSoftFloat() const override
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
std::pair< SDValue, SDValue > makeExternalCall(SDValue Chain, SelectionDAG &DAG, const char *CalleeName, EVT RetVT, ArrayRef< SDValue > Ops, CallingConv::ID CallConv, bool IsSigned, SDLoc DL, bool DoesNotReturn, bool IsReturnValueUsed) const
bool mayBeEmittedAsTailCall(const CallInst *CI) const override
Return true if the target may be able emit the call instruction as a tail call.
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
SystemZTargetLowering(const TargetMachine &TM, const SystemZSubtarget &STI)
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
bool isLegalICmpImmediate(int64_t Imm) const override
Return true if the specified immediate is legal icmp immediate, that is the target has icmp instructi...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
TargetLowering::ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AS, Align Alignment, MachineMemOperand::Flags Flags, unsigned *Fast) const override
Determine if the target supports unaligned memory accesses.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
TargetLowering::ConstraintType getConstraintType(StringRef Constraint) const override
Given a constraint, return the type of constraint it is for this target.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL, const SDValue *Parts, unsigned NumParts, MVT PartVT, EVT ValueVT, std::optional< CallingConv::ID > CC) const override
Target-specific combining of register parts into its original value.
bool isTruncateFree(Type *, Type *) const override
Return true if it's free to truncate a value of type FromTy to type ToTy.
SDValue useLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, MVT VT, SDValue Arg, SDLoc DL, SDValue Chain, bool IsStrict) const
unsigned ComputeNumSignBitsForTargetNode(SDValue Op, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth) const override
Determine the number of bits in the operation that are sign bits.
void LowerOperationWrapper(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked by the type legalizer to legalize nodes with an illegal operand type but leg...
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue LowerCall(CallLoweringInfo &CLI, SmallVectorImpl< SDValue > &InVals) const override
This hook must be implemented to lower calls into the specified DAG.
bool isLegalAddImmediate(int64_t Imm) const override
Return true if the specified immediate is legal add immediate, that is the target has add instruction...
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
This callback is invoked when a node result type is illegal for the target, and the operation was reg...
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
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.
int getCallFrameSize() final
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
virtual unsigned getNumRegistersForCallingConv(LLVMContext &Context, CallingConv::ID CC, EVT VT) const
Certain targets require unusual breakdowns of certain types.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setAtomicLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Let target indicate that an extending atomic load of the specified type is legal.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
virtual const TargetRegisterClass * getRepRegClassFor(MVT VT) const
Return the 'representative' register class for the specified value type.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS=0) const
Return the in-memory pointer type for the given address space, defaults to the pointer type from the ...
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
LegalizeAction getOperationAction(unsigned Op, EVT VT) const
Return how this operation should be treated: either it is legal, needs to be promoted to a larger siz...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual bool findOptimalMemOpLowering(LLVMContext &Context, std::vector< EVT > &MemOps, unsigned Limit, const MemOp &Op, unsigned DstAS, unsigned SrcAS, const AttributeList &FuncAttributes) const
Determines the optimal series of memory ops to replace the memset / memcpy.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
unsigned getPointerSize(unsigned AS) const
Get the pointer size for this target.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
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
self_iterator getIterator()
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 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.
@ 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.
LLVM_ABI Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
LLVM_ABI Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none.
@ Define
Register definition.
@ System
Synchronized with respect to all concurrently executing threads.
@ MO_ADA_DATA_SYMBOL_ADDR
@ MO_ADA_DIRECT_FUNC_DESC
@ MO_ADA_INDIRECT_FUNC_DESC
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned VR16Regs[32]
const unsigned GR128Regs[16]
const unsigned FP32Regs[16]
const unsigned FP16Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const int64_t ELFCallFrameSize
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned VR32Regs[32]
unsigned odd128(bool Is32bit)
const unsigned CCMASK_CMP_GE
static bool isImmHH(uint64_t Val)
const unsigned CCMASK_TEND
const unsigned CCMASK_CS_EQ
const unsigned CCMASK_TBEGIN
const MCPhysReg ELFArgFPRs[ELFNumArgFPRs]
MachineBasicBlock * splitBlockBefore(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_TM_SOME_1
const unsigned CCMASK_LOGICAL_CARRY
const unsigned TDCMASK_NORMAL_MINUS
const unsigned CCMASK_TDC
const unsigned CCMASK_FCMP
const unsigned CCMASK_TM_SOME_0
static bool isImmHL(uint64_t Val)
const unsigned TDCMASK_SUBNORMAL_MINUS
const unsigned TDCMASK_NORMAL_PLUS
const unsigned CCMASK_CMP_GT
const unsigned TDCMASK_QNAN_MINUS
const unsigned CCMASK_ANY
const unsigned CCMASK_ARITH
const unsigned CCMASK_TM_MIXED_MSB_0
const unsigned TDCMASK_SUBNORMAL_PLUS
static bool isImmLL(uint64_t Val)
const unsigned VectorBits
static bool isImmLH(uint64_t Val)
MachineBasicBlock * emitBlockAfter(MachineBasicBlock *MBB)
const unsigned TDCMASK_INFINITY_PLUS
unsigned reverseCCMask(unsigned CCMask)
const unsigned CCMASK_TM_ALL_0
const unsigned CCMASK_CMP_LE
const unsigned CCMASK_CMP_O
const unsigned CCMASK_CMP_EQ
const unsigned VectorBytes
const unsigned TDCMASK_INFINITY_MINUS
const unsigned CCMASK_ICMP
const unsigned CCMASK_VCMP_ALL
const unsigned CCMASK_VCMP_NONE
MachineBasicBlock * splitBlockAfter(MachineBasicBlock::iterator MI, MachineBasicBlock *MBB)
const unsigned CCMASK_VCMP
const unsigned CCMASK_TM_MIXED_MSB_1
const unsigned CCMASK_TM_MSB_0
const unsigned CCMASK_ARITH_OVERFLOW
const unsigned CCMASK_CS_NE
const unsigned TDCMASK_SNAN_PLUS
const unsigned CCMASK_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
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
support::ulittle32_t Word
NodeAddr< CodeNode * > Code
constexpr const char32_t SBase
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
testing::Matcher< const detail::ErrorHolder & > Failed()
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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)
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Mul
Product of integers.
DWARFExpression::Operation Op
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
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
AddressingMode(bool LongDispl, bool IdxReg)
This struct is a compact representation of a valid (non-zero power of two) alignment.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
bool isRound() const
Return true if the size is a power-of-two number of bytes.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
bool isInteger() const
Return true if this is an integer or a vector integer type.
KnownBits anyextOrTrunc(unsigned BitWidth) const
Return known bits for an "any" extension or truncation of the value we're tracking.
unsigned getBitWidth() const
Get the bit width of this value.
KnownBits zext(unsigned BitWidth) const
Return known bits for a zero extension of the value we're tracking.
void resetAll()
Resets the known state of all bits.
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
KnownBits sext(unsigned BitWidth) const
Return known bits for a sign extension of the value we're tracking.
APInt getMaxValue() const
Return the maximal unsigned value possible given these KnownBits.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
const uint32_t * getNoPreservedMask() const override
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.