69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
149 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
153 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
154 "function to use initial-exec"));
159 "Number of shuffles lowered to a VPERM or XXPERM");
160STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
181 initializeAddrModeMap();
184 bool isPPC64 = Subtarget.isPPC64();
186 const MVT RegVT = Subtarget.getScalarIntVT();
194 if (!Subtarget.hasEFPU2())
211 if (!Subtarget.hasP10Vector()) {
240 if (Subtarget.isISA3_0()) {
273 if (!Subtarget.hasSPE()) {
280 if (Subtarget.useCRBits()) {
283 if (isPPC64 || Subtarget.hasFPCVT()) {
349 if (Subtarget.isISA3_0()) {
384 if (!Subtarget.hasSPE()) {
389 if (Subtarget.hasVSX()) {
394 if (Subtarget.hasFSQRT()) {
399 if (Subtarget.hasFPRND()) {
440 if (Subtarget.hasSPE()) {
450 if (Subtarget.hasSPE())
454 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
457 if (!Subtarget.hasFSQRT() &&
458 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
461 if (Subtarget.hasFCPSGN()) {
469 if (Subtarget.hasFPRND()) {
483 if (Subtarget.isISA3_1()) {
489 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
493 if (Subtarget.isISA3_0()) {
513 if (!Subtarget.useCRBits()) {
526 if (!Subtarget.useCRBits())
529 if (Subtarget.hasFPU()) {
540 if (!Subtarget.useCRBits())
545 if (Subtarget.hasSPE()) {
569 if (Subtarget.hasDirectMove() && isPPC64) {
629 if (Subtarget.is64BitELFABI()) {
640 }
else if (Subtarget.is32BitELFABI()) {
648 if (Subtarget.is32BitELFABI())
664 if (Subtarget.isISA3_0() && isPPC64) {
691 if (Subtarget.hasSPE()) {
713 if (Subtarget.has64BitSupport()) {
728 if (Subtarget.hasLFIWAX() || isPPC64) {
734 if (Subtarget.hasSPE()) {
744 if (Subtarget.hasFPCVT()) {
745 if (Subtarget.has64BitSupport()) {
766 if (Subtarget.use64BitRegs()) {
784 if (Subtarget.has64BitSupport()) {
791 if (Subtarget.hasVSX()) {
800 if (Subtarget.hasAltivec()) {
801 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
816 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
829 if (Subtarget.hasVSX()) {
835 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
845 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
919 if (!Subtarget.hasP8Vector()) {
961 if (Subtarget.hasAltivec())
962 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
965 if (Subtarget.hasP8Altivec())
976 if (Subtarget.hasVSX()) {
982 if (Subtarget.hasP8Altivec())
987 if (Subtarget.isISA3_1()) {
1033 if (Subtarget.hasVSX()) {
1036 if (Subtarget.hasP8Vector()) {
1040 if (Subtarget.hasDirectMove() && isPPC64) {
1089 if (Subtarget.hasP8Vector())
1098 if (Subtarget.hasP8Altivec()) {
1125 if (Subtarget.isISA3_1())
1228 if (Subtarget.hasP8Altivec()) {
1233 if (Subtarget.hasP9Vector()) {
1238 if (Subtarget.useCRBits()) {
1298 }
else if (Subtarget.hasVSX()) {
1323 for (
MVT VT : {MVT::f32, MVT::f64}) {
1342 if (Subtarget.hasP9Altivec()) {
1343 if (Subtarget.isISA3_1()) {
1366 if (Subtarget.hasP10Vector()) {
1371 if (Subtarget.pairedVectorMemops()) {
1376 if (Subtarget.hasMMA()) {
1377 if (Subtarget.isISAFuture()) {
1393 if (Subtarget.has64BitSupport())
1396 if (Subtarget.isISA3_1())
1414 if (Subtarget.hasAltivec()) {
1431 if (Subtarget.hasFPCVT())
1434 if (Subtarget.useCRBits())
1443 if (Subtarget.useCRBits()) {
1449 if (Subtarget.useCRBits()) {
1465 auto CPUDirective = Subtarget.getCPUDirective();
1466 switch (CPUDirective) {
1489 if (Subtarget.enableMachineScheduler())
1563void PPCTargetLowering::initializeAddrModeMap() {
1614 if (MaxAlign == MaxMaxAlign)
1617 if (MaxMaxAlign >= 32 &&
1618 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1619 MaxAlign =
Align(32);
1620 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1622 MaxAlign =
Align(16);
1626 if (EltAlign > MaxAlign)
1627 MaxAlign = EltAlign;
1629 for (
auto *EltTy : STy->elements()) {
1632 if (EltAlign > MaxAlign)
1633 MaxAlign = EltAlign;
1634 if (MaxAlign == MaxMaxAlign)
1647 if (Subtarget.hasAltivec())
1653 return Subtarget.useSoftFloat();
1657 return Subtarget.hasSPE();
1665 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1666 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1670 if (VTy->getScalarType()->isIntegerTy()) {
1672 if (ElemSizeInBits == 32) {
1673 Index = Subtarget.isLittleEndian() ? 2 : 1;
1676 if (ElemSizeInBits == 64) {
1677 Index = Subtarget.isLittleEndian() ? 1 : 0;
1688 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1705 return CFP->getValueAPF().isZero();
1710 return CFP->getValueAPF().isZero();
1718 return Op < 0 ||
Op == Val;
1730 if (ShuffleKind == 0) {
1733 for (
unsigned i = 0; i != 16; ++i)
1736 }
else if (ShuffleKind == 2) {
1739 for (
unsigned i = 0; i != 16; ++i)
1742 }
else if (ShuffleKind == 1) {
1743 unsigned j = IsLE ? 0 : 1;
1744 for (
unsigned i = 0; i != 8; ++i)
1761 if (ShuffleKind == 0) {
1764 for (
unsigned i = 0; i != 16; i += 2)
1768 }
else if (ShuffleKind == 2) {
1771 for (
unsigned i = 0; i != 16; i += 2)
1775 }
else if (ShuffleKind == 1) {
1776 unsigned j = IsLE ? 0 : 2;
1777 for (
unsigned i = 0; i != 8; i += 2)
1798 if (!Subtarget.hasP8Vector())
1802 if (ShuffleKind == 0) {
1805 for (
unsigned i = 0; i != 16; i += 4)
1811 }
else if (ShuffleKind == 2) {
1814 for (
unsigned i = 0; i != 16; i += 4)
1820 }
else if (ShuffleKind == 1) {
1821 unsigned j = IsLE ? 0 : 4;
1822 for (
unsigned i = 0; i != 8; i += 4)
1839 unsigned LHSStart,
unsigned RHSStart) {
1840 if (
N->getValueType(0) != MVT::v16i8)
1842 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1843 "Unsupported merge size!");
1845 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1846 for (
unsigned j = 0; j != UnitSize; ++j) {
1848 LHSStart+j+i*UnitSize) ||
1850 RHSStart+j+i*UnitSize))
1865 if (ShuffleKind == 1)
1867 else if (ShuffleKind == 2)
1872 if (ShuffleKind == 1)
1874 else if (ShuffleKind == 0)
1890 if (ShuffleKind == 1)
1892 else if (ShuffleKind == 2)
1897 if (ShuffleKind == 1)
1899 else if (ShuffleKind == 0)
1949 unsigned RHSStartValue) {
1950 if (
N->getValueType(0) != MVT::v16i8)
1953 for (
unsigned i = 0; i < 2; ++i)
1954 for (
unsigned j = 0; j < 4; ++j)
1956 i*RHSStartValue+j+IndexOffset) ||
1958 i*RHSStartValue+j+IndexOffset+8))
1980 unsigned indexOffset = CheckEven ? 4 : 0;
1981 if (ShuffleKind == 1)
1983 else if (ShuffleKind == 2)
1989 unsigned indexOffset = CheckEven ? 0 : 4;
1990 if (ShuffleKind == 1)
1992 else if (ShuffleKind == 0)
2008 if (
N->getValueType(0) != MVT::v16i8)
2015 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2018 if (i == 16)
return -1;
2023 if (ShiftAmt < i)
return -1;
2028 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2030 for (++i; i != 16; ++i)
2033 }
else if (ShuffleKind == 1) {
2035 for (++i; i != 16; ++i)
2042 ShiftAmt = 16 - ShiftAmt;
2051 EVT VT =
N->getValueType(0);
2052 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2053 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2056 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2060 if (
N->getMaskElt(0) % EltSize != 0)
2065 unsigned ElementBase =
N->getMaskElt(0);
2068 if (ElementBase >= 16)
2073 for (
unsigned i = 1; i != EltSize; ++i)
2074 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2077 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2079 if (
N->getMaskElt(i) < 0) {
2080 for (
unsigned j = 1; j != EltSize; ++j)
2081 if (
N->getMaskElt(i + j) >= 0)
2084 for (
unsigned j = 0; j != EltSize; ++j)
2085 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2102 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2103 "Unexpected element width.");
2104 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2106 unsigned NumOfElem = 16 / Width;
2107 unsigned MaskVal[16];
2108 for (
unsigned i = 0; i < NumOfElem; ++i) {
2109 MaskVal[0] =
N->getMaskElt(i * Width);
2110 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2112 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2116 for (
unsigned int j = 1; j < Width; ++j) {
2117 MaskVal[j] =
N->getMaskElt(i * Width + j);
2118 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2128 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2133 unsigned M0 =
N->getMaskElt(0) / 4;
2134 unsigned M1 =
N->getMaskElt(4) / 4;
2135 unsigned M2 =
N->getMaskElt(8) / 4;
2136 unsigned M3 =
N->getMaskElt(12) / 4;
2137 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2138 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2143 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2144 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2145 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2146 InsertAtByte = IsLE ? 12 : 0;
2151 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2152 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2153 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2154 InsertAtByte = IsLE ? 8 : 4;
2159 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2160 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2161 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2162 InsertAtByte = IsLE ? 4 : 8;
2167 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2168 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2169 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2170 InsertAtByte = IsLE ? 0 : 12;
2177 if (
N->getOperand(1).isUndef()) {
2180 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2181 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2182 InsertAtByte = IsLE ? 12 : 0;
2185 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2186 InsertAtByte = IsLE ? 8 : 4;
2189 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2190 InsertAtByte = IsLE ? 4 : 8;
2193 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2194 InsertAtByte = IsLE ? 0 : 12;
2203 bool &Swap,
bool IsLE) {
2204 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2210 unsigned M0 =
N->getMaskElt(0) / 4;
2211 unsigned M1 =
N->getMaskElt(4) / 4;
2212 unsigned M2 =
N->getMaskElt(8) / 4;
2213 unsigned M3 =
N->getMaskElt(12) / 4;
2217 if (
N->getOperand(1).isUndef()) {
2218 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2219 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2222 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2228 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2232 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2237 ShiftElts = (8 -
M0) % 8;
2238 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2243 ShiftElts = (4 -
M0) % 4;
2248 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2253 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2265 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2270 for (
int i = 0; i < 16; i += Width)
2271 if (
N->getMaskElt(i) != i + Width - 1)
2302 bool &Swap,
bool IsLE) {
2303 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2309 unsigned M0 =
N->getMaskElt(0) / 8;
2310 unsigned M1 =
N->getMaskElt(8) / 8;
2311 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2315 if (
N->getOperand(1).isUndef()) {
2316 if ((
M0 |
M1) < 2) {
2317 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2325 if (
M0 > 1 &&
M1 < 2) {
2335 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2340 }
else if (
M0 > 1 &&
M1 < 2) {
2348 DM = (
M0 << 1) + (
M1 & 1);
2363 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2368 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2384 unsigned EltSize = 16/
N->getNumOperands();
2385 if (EltSize < ByteSize) {
2386 unsigned Multiple = ByteSize/EltSize;
2388 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2391 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2392 if (
N->getOperand(i).isUndef())
continue;
2396 if (!UniquedVals[i&(Multiple-1)].
getNode())
2397 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2398 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2408 bool LeadingZero =
true;
2409 bool LeadingOnes =
true;
2410 for (
unsigned i = 0; i != Multiple-1; ++i) {
2411 if (!UniquedVals[i].
getNode())
continue;
2418 if (!UniquedVals[Multiple-1].
getNode())
2425 if (!UniquedVals[Multiple-1].
getNode())
2436 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2437 if (
N->getOperand(i).isUndef())
continue;
2439 OpVal =
N->getOperand(i);
2440 else if (OpVal !=
N->getOperand(i))
2446 unsigned ValSizeInBytes = EltSize;
2449 Value = CN->getZExtValue();
2451 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2458 if (ValSizeInBytes < ByteSize)
return SDValue();
2469 if (MaskVal == 0)
return SDValue();
2489 Imm = (int16_t)
N->getAsZExtVal();
2490 if (
N->getValueType(0) == MVT::i32)
2491 return Imm == (int32_t)
N->getAsZExtVal();
2493 return Imm == (int64_t)
N->getAsZExtVal();
2511 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2519 for (
SDNode *U :
N->users()) {
2521 if (Memop->getMemoryVT() == MVT::f64) {
2522 Base =
N.getOperand(0);
2523 Index =
N.getOperand(1);
2566 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2568 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2571 Base =
N.getOperand(0);
2572 Index =
N.getOperand(1);
2574 }
else if (
N.getOpcode() ==
ISD::OR) {
2576 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2588 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2589 Base =
N.getOperand(0);
2590 Index =
N.getOperand(1);
2660 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2666 Base =
N.getOperand(0);
2669 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2671 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2672 "Cannot handle constant offsets yet!");
2673 Disp =
N.getOperand(1).getOperand(0);
2678 Base =
N.getOperand(0);
2681 }
else if (
N.getOpcode() ==
ISD::OR) {
2684 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2698 Base =
N.getOperand(0);
2711 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2714 CN->getValueType(0));
2719 if ((CN->getValueType(0) == MVT::i32 ||
2720 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2721 (!EncodingAlignment ||
2722 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2723 int Addr = (int)CN->getZExtValue();
2730 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2751 if (
N.getValueType() != MVT::i64)
2764 Base =
N.getOperand(0);
2780 Base =
N.getOperand(0);
2813 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2814 Base =
N.getOperand(0);
2815 Index =
N.getOperand(1);
2837 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2858 EVT MemVT = LD->getMemoryVT();
2865 if (!ST.hasP8Vector())
2870 if (!ST.hasP9Vector())
2882 if (
Use.getResNo() == 0 &&
2884 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2904 Ptr = LD->getBasePtr();
2905 VT = LD->getMemoryVT();
2906 Alignment = LD->getAlign();
2908 Ptr = ST->getBasePtr();
2909 VT = ST->getMemoryVT();
2910 Alignment = ST->getAlign();
2949 if (VT != MVT::i64) {
2954 if (Alignment <
Align(4))
2964 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
2981 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3023 EVT VT = Subtarget.getScalarIntVT();
3025 : Subtarget.isAIXABI()
3030 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3037 EVT PtrVT =
Op.getValueType();
3043 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3044 if (Subtarget.isUsingPCRelativeCalls()) {
3049 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3053 return getTOCEntry(DAG, SDLoc(CP), GA);
3056 unsigned MOHiFlag, MOLoFlag;
3060 if (IsPIC && Subtarget.isSVR4ABI()) {
3063 return getTOCEntry(DAG, SDLoc(CP), GA);
3086 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3093 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3110 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3123 EVT PtrVT =
Op.getValueType();
3141 return getTOCEntry(DAG,
SDLoc(JT), GA);
3144 unsigned MOHiFlag, MOLoFlag;
3148 if (IsPIC && Subtarget.isSVR4ABI()) {
3151 return getTOCEntry(DAG, SDLoc(GA), GA);
3161 EVT PtrVT =
Op.getValueType();
3166 if (Subtarget.isUsingPCRelativeCalls()) {
3177 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3180 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3189 unsigned MOHiFlag, MOLoFlag;
3199 if (Subtarget.isAIXABI())
3200 return LowerGlobalTLSAddressAIX(
Op, DAG);
3202 return LowerGlobalTLSAddressLinux(
Op, DAG);
3224 if (
I.getOpcode() == Instruction::Call)
3226 if (
Function *CF = CI->getCalledFunction())
3227 if (CF->isDeclaration() &&
3228 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3236 unsigned TLSGVCnt = TLSGV.
size();
3246 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3259 const GlobalValue *GV = GA->
getGlobal();
3261 bool Is64Bit = Subtarget.isPPC64();
3265 if (Subtarget.hasAIXShLibTLSModelOpt())
3275 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3276 bool HasAIXSmallTLSGlobalAttr =
false;
3279 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3283 if (GVar->hasAttribute(
"aix-small-tls"))
3284 HasAIXSmallTLSGlobalAttr =
true;
3303 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3304 IsTLSLocalExecModel) {
3309 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3319 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3324 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3326 "currently only supported on AIX (64-bit mode).");
3328 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3332 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3336 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3338 "currently only supported on AIX (64-bit mode).");
3346 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3349 GlobalVariable *TLSGV =
3353 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3356 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3358 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3367 if (HasAIXSmallLocalDynamicTLS) {
3372 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3376 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3389 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3390 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3391 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3406 const GlobalValue *GV = GA->
getGlobal();
3408 bool is64bit = Subtarget.isPPC64();
3416 if (Subtarget.isUsingPCRelativeCalls()) {
3421 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3422 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3433 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3437 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3444 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3446 MachinePointerInfo());
3453 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3455 if (!TM.isPositionIndependent())
3456 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3462 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3464 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3468 if (Subtarget.isUsingPCRelativeCalls()) {
3471 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3479 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3487 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3492 if (Subtarget.isUsingPCRelativeCalls()) {
3496 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3497 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3505 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3514 PtrVT, GOTPtr, TGA, TGA);
3516 PtrVT, TLSAddr, TGA);
3517 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3525 EVT PtrVT =
Op.getValueType();
3528 const GlobalValue *GV = GSDN->
getGlobal();
3532 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3533 if (Subtarget.isUsingPCRelativeCalls()) {
3540 MachinePointerInfo());
3545 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3550 return getTOCEntry(DAG,
DL, GA);
3553 unsigned MOHiFlag, MOLoFlag;
3557 if (IsPIC && Subtarget.isSVR4ABI()) {
3561 return getTOCEntry(DAG,
DL, GA);
3573 bool IsStrict =
Op->isStrictFPOpcode();
3579 EVT LHSVT =
LHS.getValueType();
3583 if (LHSVT == MVT::f128) {
3584 assert(!Subtarget.hasP9Vector() &&
3585 "SETCC for f128 is already legal under Power9!");
3596 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3598 if (
Op.getValueType() == MVT::v2i64) {
3601 if (
LHS.getValueType() == MVT::v2i64) {
3607 dl, MVT::v4i32, DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
LHS),
3608 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
RHS), CC);
3609 int ShuffV[] = {1, 0, 3, 2};
3614 dl, MVT::v4i32, Shuff, SetCC32));
3631 if (
C->isAllOnes() ||
C->isZero())
3641 EVT VT =
Op.getValueType();
3649 SDNode *
Node =
Op.getNode();
3650 EVT VT =
Node->getValueType(0);
3657 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3661 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3664 if (VT == MVT::i64) {
3683 FprPtr, MachinePointerInfo(SV), MVT::i8);
3694 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3695 InChain = OverflowArea.
getValue(1);
3698 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3728 MachinePointerInfo(SV), MVT::i8);
3741 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3742 MachinePointerInfo(), MVT::i32);
3744 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3748 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3754 false,
true,
nullptr, std::nullopt,
3755 MachinePointerInfo(), MachinePointerInfo());
3760 return Op.getOperand(0);
3765 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3767 assert((
Op.getOpcode() == ISD::INLINEASM ||
3768 Op.getOpcode() == ISD::INLINEASM_BR) &&
3769 "Expecting Inline ASM node.");
3779 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3784 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3785 unsigned NumVals =
Flags.getNumOperandRegisters();
3788 switch (
Flags.getKind()) {
3799 for (; NumVals; --NumVals, ++i) {
3801 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3824 if (Subtarget.isAIXABI()) {
3828 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3829 MaybeAlign PointerAlign(PointerSize);
3830 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3833 : MachineMemOperand::MONone;
3840 const Value *TrampolineAddr =
3850 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3851 PointerAlign, MMOFlags);
3853 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3854 MachinePointerInfo(TrampolineAddr, 0));
3858 SDValue TOCFromDescriptorPtr =
3860 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3861 MachinePointerInfo(Func, TOCPointerOffset),
3862 PointerAlign, MMOFlags);
3863 SDValue TrampolineTOCPointer =
3867 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3868 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3874 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3875 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3882 bool isPPC64 = (PtrVT == MVT::i64);
3886 Args.emplace_back(Trmp, IntPtrTy);
3889 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3891 Args.emplace_back(FPtr, IntPtrTy);
3892 Args.emplace_back(Nest, IntPtrTy);
3895 TargetLowering::CallLoweringInfo CLI(DAG);
3896 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3900 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3901 return CallResult.second;
3906 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3911 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3916 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3917 MachinePointerInfo(SV));
3951 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3954 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3957 uint64_t FPROffset = 1;
3965 MachinePointerInfo(SV), MVT::i8);
3966 uint64_t nextOffset = FPROffset;
3973 MachinePointerInfo(SV, nextOffset), MVT::i8);
3974 nextOffset += StackOffset;
3975 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3978 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3979 MachinePointerInfo(SV, nextOffset));
3980 nextOffset += FrameOffset;
3981 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3984 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3985 MachinePointerInfo(SV, nextOffset));
3990static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3991 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
3992 PPC::F11, PPC::F12, PPC::F13};
3997 unsigned PtrByteSize) {
3999 if (Flags.isByVal())
4000 ArgSize = Flags.getByValSize();
4004 if (!Flags.isInConsecutiveRegs())
4005 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4014 unsigned PtrByteSize) {
4015 Align Alignment(PtrByteSize);
4018 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4019 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4020 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4021 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4022 Alignment =
Align(16);
4025 if (Flags.isByVal()) {
4026 auto BVAlign = Flags.getNonZeroByValAlign();
4027 if (BVAlign > PtrByteSize) {
4028 if (BVAlign.value() % PtrByteSize != 0)
4030 "ByVal alignment is not a multiple of the pointer size");
4032 Alignment = BVAlign;
4037 if (Flags.isInConsecutiveRegs()) {
4041 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4055 unsigned PtrByteSize,
unsigned LinkageSize,
4056 unsigned ParamAreaSize,
unsigned &ArgOffset,
4057 unsigned &AvailableFPRs,
4058 unsigned &AvailableVRs) {
4059 bool UseMemory =
false;
4064 ArgOffset =
alignTo(ArgOffset, Alignment);
4067 if (ArgOffset >= LinkageSize + ParamAreaSize)
4072 if (Flags.isInConsecutiveRegsLast())
4073 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4076 if (ArgOffset > LinkageSize + ParamAreaSize)
4081 if (!Flags.isByVal()) {
4082 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4083 if (AvailableFPRs > 0) {
4087 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4088 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4089 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4090 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4091 if (AvailableVRs > 0) {
4103 unsigned NumBytes) {
4107SDValue PPCTargetLowering::LowerFormalArguments(
4111 if (Subtarget.isAIXABI())
4112 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4114 if (Subtarget.is64BitELFABI())
4115 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4117 assert(Subtarget.is32BitELFABI());
4118 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4122SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4158 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4164 const Align PtrAlign(4);
4172 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4173 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4176 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4177 CCValAssign &VA = ArgLocs[i];
4181 const TargetRegisterClass *RC;
4189 RC = &PPC::GPRCRegClass;
4192 if (Subtarget.hasP8Vector())
4193 RC = &PPC::VSSRCRegClass;
4194 else if (Subtarget.hasSPE())
4195 RC = &PPC::GPRCRegClass;
4197 RC = &PPC::F4RCRegClass;
4200 if (Subtarget.hasVSX())
4201 RC = &PPC::VSFRCRegClass;
4202 else if (Subtarget.hasSPE())
4204 RC = &PPC::GPRCRegClass;
4206 RC = &PPC::F8RCRegClass;
4211 RC = &PPC::VRRCRegClass;
4214 RC = &PPC::VRRCRegClass;
4218 RC = &PPC::VRRCRegClass;
4225 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4226 assert(i + 1 < e &&
"No second half of double precision argument");
4231 if (!Subtarget.isLittleEndian())
4233 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4238 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4239 if (ValVT == MVT::i1)
4254 ArgOffset += ArgSize - ObjSize;
4272 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4277 unsigned MinReservedArea = CCByValInfo.getStackSize();
4278 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4294 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4295 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4297 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4300 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4303 unsigned NumFPArgRegs = std::size(FPArgRegs);
4312 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4313 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4316 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4329 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4344 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4348 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4361 if (!MemOps.
empty())
4372 const SDLoc &dl)
const {
4376 else if (
Flags.isZExt())
4383SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4389 bool isELFv2ABI = Subtarget.isELFv2ABI();
4390 bool isLittleEndian = Subtarget.isLittleEndian();
4393 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4396 "fastcc not supported on varargs functions");
4402 unsigned PtrByteSize = 8;
4403 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4406 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4407 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4410 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4411 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4414 const unsigned Num_GPR_Regs = std::size(GPR);
4416 const unsigned Num_VR_Regs = std::size(VR);
4424 bool HasParameterArea = !isELFv2ABI || isVarArg;
4425 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4426 unsigned NumBytes = LinkageSize;
4427 unsigned AvailableFPRs = Num_FPR_Regs;
4428 unsigned AvailableVRs = Num_VR_Regs;
4429 for (
const ISD::InputArg &In : Ins) {
4430 if (
In.Flags.isNest())
4434 LinkageSize, ParamAreaSize, NumBytes,
4435 AvailableFPRs, AvailableVRs))
4436 HasParameterArea =
true;
4443 unsigned ArgOffset = LinkageSize;
4444 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4447 unsigned CurArgIdx = 0;
4448 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4450 bool needsLoad =
false;
4451 EVT ObjectVT =
Ins[ArgNo].VT;
4452 EVT OrigVT =
Ins[ArgNo].ArgVT;
4454 unsigned ArgSize = ObjSize;
4455 ISD::ArgFlagsTy
Flags =
Ins[ArgNo].Flags;
4456 if (Ins[ArgNo].isOrigArg()) {
4457 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4458 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4463 unsigned CurArgOffset;
4465 auto ComputeArgOffset = [&]() {
4469 ArgOffset =
alignTo(ArgOffset, Alignment);
4470 CurArgOffset = ArgOffset;
4477 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4478 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4483 if (
Flags.isByVal()) {
4484 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4490 ObjSize =
Flags.getByValSize();
4491 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4513 if (HasParameterArea ||
4514 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4521 if (ObjSize < PtrByteSize) {
4525 if (!isLittleEndian) {
4531 if (GPR_idx != Num_GPR_Regs) {
4538 MachinePointerInfo(&*FuncArg), ObjType);
4543 ArgOffset += PtrByteSize;
4552 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4553 if (GPR_idx == Num_GPR_Regs)
4564 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4568 MachinePointerInfo(&*FuncArg, j), ObjType);
4572 ArgOffset += ArgSize;
4581 if (
Flags.isNest()) {
4586 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4587 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4595 if (GPR_idx != Num_GPR_Regs) {
4600 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4603 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4609 ArgSize = PtrByteSize;
4620 if (FPR_idx != Num_FPR_Regs) {
4623 if (ObjectVT == MVT::f32)
4625 Subtarget.hasP8Vector()
4626 ? &PPC::VSSRCRegClass
4627 : &PPC::F4RCRegClass);
4630 ? &PPC::VSFRCRegClass
4631 : &PPC::F8RCRegClass);
4646 if (ObjectVT == MVT::f32) {
4647 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4653 ArgVal = DAG.
getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
4665 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4666 ArgOffset += ArgSize;
4667 if (
Flags.isInConsecutiveRegsLast())
4668 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4682 if (VR_idx != Num_VR_Regs) {
4699 if (ObjSize < ArgSize && !isLittleEndian)
4700 CurArgOffset += ArgSize - ObjSize;
4703 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4710 unsigned MinReservedArea;
4711 if (HasParameterArea)
4712 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4714 MinReservedArea = LinkageSize;
4731 int Depth = ArgOffset;
4740 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4741 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4753 if (!MemOps.
empty())
4762 unsigned ParamSize) {
4764 if (!isTailCall)
return 0;
4768 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4770 if (SPDiff < FI->getTailCallSPDelta())
4786 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4845 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4848 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4860 const unsigned PtrByteSize = 8;
4864 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4865 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4868 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4869 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4872 const unsigned NumGPRs = std::size(GPR);
4873 const unsigned NumFPRs = 13;
4874 const unsigned NumVRs = std::size(VR);
4875 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4877 unsigned NumBytes = LinkageSize;
4878 unsigned AvailableFPRs = NumFPRs;
4879 unsigned AvailableVRs = NumVRs;
4882 if (Param.Flags.isNest())
continue;
4885 LinkageSize, ParamAreaSize, NumBytes,
4886 AvailableFPRs, AvailableVRs))
4897 auto CalleeArgEnd = CB.
arg_end();
4900 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4901 const Value* CalleeArg = *CalleeArgIter;
4902 const Value* CallerArg = &(*CallerArgIter);
4903 if (CalleeArg == CallerArg)
4929 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4939bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4944 bool isCalleeExternalSymbol)
const {
4947 if (
DisableSCO && !TailCallOpt)
return false;
4950 if (isVarArg)
return false;
4957 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
4993 if (!Subtarget.isUsingPCRelativeCalls() &&
4998 if (!Subtarget.isUsingPCRelativeCalls() &&
5026bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5039 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5060 if (!
C)
return nullptr;
5062 int Addr =
C->getZExtValue();
5063 if ((Addr & 3) != 0 ||
5069 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5076struct TailCallArgumentInfo {
5081 TailCallArgumentInfo() =
default;
5091 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5092 SDValue Arg = TailCallArgs[i].Arg;
5093 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5094 int FI = TailCallArgs[i].FrameIdx;
5097 Chain, dl, Arg, FIN,
5106 int SPDiff,
const SDLoc &dl) {
5112 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5113 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5115 NewRetAddrLoc,
true);
5118 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5128 int SPDiff,
unsigned ArgOffset,
5130 int Offset = ArgOffset + SPDiff;
5133 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5135 TailCallArgumentInfo
Info;
5137 Info.FrameIdxOp = FIN;
5145SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5150 LROpOut = getReturnAddrFrameIndex(DAG);
5151 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5152 MachinePointerInfo());
5169 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5177 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5201 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5211 if (!MemOpChains2.
empty())
5235SDValue PPCTargetLowering::LowerCallResult(
5243 CCRetInfo.AnalyzeCallResult(
5249 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5250 CCValAssign &VA = RVLocs[i];
5255 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5265 if (!Subtarget.isLittleEndian())
5267 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5333 bool IsStrictFPCall =
false) {
5335 return PPCISD::TC_RETURN;
5337 unsigned RetOpc = 0;
5352 RetOpc = PPCISD::CALL_NOTOC;
5367 RetOpc = PPCISD::CALL;
5368 if (IsStrictFPCall) {
5372 case PPCISD::BCTRL_LOAD_TOC:
5373 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5376 RetOpc = PPCISD::BCTRL_RM;
5378 case PPCISD::CALL_NOTOC:
5379 RetOpc = PPCISD::CALL_NOTOC_RM;
5382 RetOpc = PPCISD::CALL_RM;
5384 case PPCISD::CALL_NOP:
5385 RetOpc = PPCISD::CALL_NOP_RM;
5399 auto isLocalCallee = [&]() {
5415 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5432 return getAIXFuncEntryPointSymbolSDNode(GV);
5439 const char *SymName = S->getSymbol();
5446 return getAIXFuncEntryPointSymbolSDNode(
F);
5452 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5460 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5467 assert(Callee.getNode() &&
"What no callee?");
5473 "Expected a CALLSEQ_STARTSDNode.");
5490 SDValue MTCTROps[] = {Chain, Callee, Glue};
5491 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5492 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5532 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5551 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5552 Alignment, MMOFlags);
5559 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5566 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5578 "Nest parameter is not supported on AIX.");
5594 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5597 const bool IsPPC64 = Subtarget.isPPC64();
5602 Ops.push_back(Chain);
5606 Ops.push_back(Callee);
5626 Ops.push_back(AddTOC);
5637 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5646 for (
const auto &[
Reg,
N] : RegsToPass)
5664 assert(Mask &&
"Missing call preserved mask for calling convention");
5669 Ops.push_back(Glue);
5672SDValue PPCTargetLowering::FinishCall(
5679 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5680 Subtarget.isAIXABI())
5687 if (!CFlags.IsIndirect)
5689 else if (Subtarget.usesFunctionDescriptors())
5691 dl, CFlags.HasNest, Subtarget);
5701 if (CFlags.IsTailCall) {
5709 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5710 "Expecting a global address, external symbol, absolute value, "
5711 "register or an indirect tail call when PC Relative calls are "
5714 assert(CallOpc == PPCISD::TC_RETURN &&
5715 "Unexpected call opcode for a tail call.");
5722 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5723 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5735 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5738 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5758 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5759 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5763bool PPCTargetLowering::isEligibleForTCO(
5768 bool isCalleeExternalSymbol)
const {
5772 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5773 return IsEligibleForTailCallOptimization_64SVR4(
5774 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5775 isCalleeExternalSymbol);
5777 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5805 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5820 "Callee should be an llvm::Function object.");
5823 <<
"\nTCO callee: ");
5830 "site marked musttail");
5837 Callee = LowerGlobalAddress(Callee, DAG);
5840 CallConv, isTailCall, isVarArg, isPatchPoint,
5843 Subtarget.is64BitELFABI() &&
5847 if (Subtarget.isAIXABI())
5848 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5851 assert(Subtarget.isSVR4ABI());
5852 if (Subtarget.isPPC64())
5853 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5855 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5859SDValue PPCTargetLowering::LowerCall_32SVR4(
5870 const bool IsVarArg = CFlags.IsVarArg;
5871 const bool IsTailCall = CFlags.IsTailCall;
5877 const Align PtrAlign(4);
5888 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5896 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5899 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5906 unsigned NumArgs = Outs.
size();
5908 for (
unsigned i = 0; i != NumArgs; ++i) {
5909 MVT ArgVT = Outs[i].VT;
5910 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5915 Outs[i].OrigTy, CCInfo);
5918 ArgFlags, Outs[i].OrigTy, CCInfo);
5923 errs() <<
"Call operand #" << i <<
" has unhandled type "
5936 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
5939 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5946 unsigned NumBytes = CCByValInfo.getStackSize();
5960 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5971 bool seenFloatArg =
false;
5976 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5978 ++i, ++RealArgIdx) {
5979 CCValAssign &VA = ArgLocs[i];
5980 SDValue Arg = OutVals[RealArgIdx];
5981 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
5983 if (
Flags.isByVal()) {
5988 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5989 CCValAssign &ByValVA = ByValArgLocs[
j++];
6011 Chain = CallSeqStart = NewCallSeqStart;
6030 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6031 bool IsLE = Subtarget.isLittleEndian();
6032 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6035 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6037 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6052 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6061 if (!MemOpChains.
empty())
6067 for (
const auto &[
Reg,
N] : RegsToPass) {
6075 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6078 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6088 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6089 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6094SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6106 return NewCallSeqStart;
6109SDValue PPCTargetLowering::LowerCall_64SVR4(
6116 bool isELFv2ABI = Subtarget.isELFv2ABI();
6117 bool isLittleEndian = Subtarget.isLittleEndian();
6119 bool IsSibCall =
false;
6123 unsigned PtrByteSize = 8;
6136 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6138 assert(!(IsFastCall && CFlags.IsVarArg) &&
6139 "fastcc not supported on varargs functions");
6145 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6146 unsigned NumBytes = LinkageSize;
6147 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6150 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6151 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6154 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6155 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6158 const unsigned NumGPRs = std::size(GPR);
6160 const unsigned NumVRs = std::size(VR);
6166 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6167 if (!HasParameterArea) {
6168 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6169 unsigned AvailableFPRs = NumFPRs;
6170 unsigned AvailableVRs = NumVRs;
6171 unsigned NumBytesTmp = NumBytes;
6172 for (
unsigned i = 0; i !=
NumOps; ++i) {
6173 if (Outs[i].
Flags.isNest())
continue;
6175 PtrByteSize, LinkageSize, ParamAreaSize,
6176 NumBytesTmp, AvailableFPRs, AvailableVRs))
6177 HasParameterArea =
true;
6183 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6188 HasParameterArea =
false;
6191 for (
unsigned i = 0; i !=
NumOps; ++i) {
6192 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6193 EVT ArgVT = Outs[i].VT;
6194 EVT OrigVT = Outs[i].ArgVT;
6200 if (
Flags.isByVal()) {
6201 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6202 if (NumGPRsUsed > NumGPRs)
6203 HasParameterArea =
true;
6210 if (++NumGPRsUsed <= NumGPRs)
6220 if (++NumVRsUsed <= NumVRs)
6224 if (++NumVRsUsed <= NumVRs)
6229 if (++NumFPRsUsed <= NumFPRs)
6233 HasParameterArea =
true;
6240 NumBytes =
alignTo(NumBytes, Alignement);
6243 if (
Flags.isInConsecutiveRegsLast())
6244 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6247 unsigned NumBytesActuallyUsed = NumBytes;
6257 if (HasParameterArea)
6258 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6260 NumBytes = LinkageSize;
6275 if (CFlags.IsTailCall)
6287 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6298 unsigned ArgOffset = LinkageSize;
6304 for (
unsigned i = 0; i !=
NumOps; ++i) {
6306 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6307 EVT ArgVT = Outs[i].VT;
6308 EVT OrigVT = Outs[i].ArgVT;
6317 auto ComputePtrOff = [&]() {
6321 ArgOffset =
alignTo(ArgOffset, Alignment);
6332 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6333 GPR_idx = std::min(GPR_idx, NumGPRs);
6340 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6346 if (
Flags.isByVal()) {
6364 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6365 if (GPR_idx != NumGPRs) {
6367 MachinePointerInfo(), VT);
6369 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6371 ArgOffset += PtrByteSize;
6376 if (GPR_idx == NumGPRs &&
Size < 8) {
6378 if (!isLittleEndian) {
6383 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6386 ArgOffset += PtrByteSize;
6395 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6396 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6401 if (
Size < 8 && GPR_idx != NumGPRs) {
6411 if (!isLittleEndian) {
6415 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6421 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6423 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6426 ArgOffset += PtrByteSize;
6432 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6435 if (GPR_idx != NumGPRs) {
6436 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6439 MachinePointerInfo(), ObjType);
6442 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6443 ArgOffset += PtrByteSize;
6445 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6457 if (
Flags.isNest()) {
6459 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6466 if (GPR_idx != NumGPRs) {
6467 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6472 assert(HasParameterArea &&
6473 "Parameter area must exist to pass an argument in memory.");
6475 true, CFlags.IsTailCall,
false, MemOpChains,
6476 TailCallArguments, dl);
6478 ArgOffset += PtrByteSize;
6481 ArgOffset += PtrByteSize;
6494 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6495 bool NeededLoad =
false;
6498 if (FPR_idx != NumFPRs)
6499 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6502 if (!NeedGPROrStack)
6504 else if (GPR_idx != NumGPRs && !IsFastCall) {
6515 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i64, Arg);
6518 }
else if (!
Flags.isInConsecutiveRegs()) {
6519 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6524 }
else if (ArgOffset % PtrByteSize != 0) {
6526 Lo = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, OutVals[i - 1]);
6527 Hi = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6528 if (!isLittleEndian)
6533 }
else if (
Flags.isInConsecutiveRegsLast()) {
6534 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6536 if (!isLittleEndian)
6546 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6554 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6559 assert(HasParameterArea &&
6560 "Parameter area must exist to pass an argument in memory.");
6562 true, CFlags.IsTailCall,
false, MemOpChains,
6563 TailCallArguments, dl);
6570 if (!IsFastCall || NeededLoad) {
6572 Flags.isInConsecutiveRegs()) ? 4 : 8;
6573 if (
Flags.isInConsecutiveRegsLast())
6574 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6594 if (CFlags.IsVarArg) {
6595 assert(HasParameterArea &&
6596 "Parameter area must exist if we have a varargs call.");
6600 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6602 if (VR_idx != NumVRs) {
6604 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6606 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6609 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6610 if (GPR_idx == NumGPRs)
6615 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6617 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6623 if (VR_idx != NumVRs) {
6624 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6629 assert(HasParameterArea &&
6630 "Parameter area must exist to pass an argument in memory.");
6632 true, CFlags.IsTailCall,
true, MemOpChains,
6633 TailCallArguments, dl);
6644 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6645 "mismatch in size of parameter area");
6646 (void)NumBytesActuallyUsed;
6648 if (!MemOpChains.
empty())
6654 if (CFlags.IsIndirect) {
6658 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6663 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6673 if (isELFv2ABI && !CFlags.IsPatchPoint)
6674 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6680 for (
const auto &[
Reg,
N] : RegsToPass) {
6685 if (CFlags.IsTailCall && !IsSibCall)
6689 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6690 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6697 "Required alignment greater than stack alignment.");
6717 return RequiredAlign <= 8;
6722 return RequiredAlign <= 4;
6730 State.getMachineFunction().getSubtarget());
6731 const bool IsPPC64 = Subtarget.isPPC64();
6732 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6733 const Align PtrAlign(PtrSize);
6734 const Align StackAlign(16);
6737 if (ValVT == MVT::f128)
6741 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6742 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6744 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6745 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6748 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6749 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6750 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6755 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6764 if (ByValAlign > StackAlign)
6766 "16 are not supported.");
6769 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6773 if (ByValSize == 0) {
6775 State.getStackSize(), RegVT, LocInfo));
6780 unsigned NextReg = State.getFirstUnallocated(GPRs);
6781 while (NextReg != GPRs.
size() &&
6786 State.AllocateStack(PtrSize, PtrAlign);
6787 assert(
Reg &&
"Alocating register unexpectedly failed.");
6789 NextReg = State.getFirstUnallocated(GPRs);
6792 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6793 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6813 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6817 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6836 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6842 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6844 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6845 if (State.isVarArg()) {
6877 const unsigned VecSize = 16;
6878 const Align VecAlign(VecSize);
6880 if (!State.isVarArg()) {
6883 if (
MCRegister VReg = State.AllocateReg(VR)) {
6890 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6895 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6898 while (NextRegIndex != GPRs.
size() &&
6902 State.AllocateStack(PtrSize, PtrAlign);
6903 assert(
Reg &&
"Allocating register unexpectedly failed.");
6905 NextRegIndex = State.getFirstUnallocated(GPRs);
6913 if (
MCRegister VReg = State.AllocateReg(VR)) {
6916 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6917 State.AllocateReg(GPRs);
6918 State.AllocateStack(VecSize, VecAlign);
6922 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6928 if (NextRegIndex == GPRs.
size()) {
6929 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6937 if (GPRs[NextRegIndex] == PPC::R9) {
6938 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6942 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
6943 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
6944 assert(FirstReg && SecondReg &&
6945 "Allocating R9 or R10 unexpectedly failed.");
6956 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6959 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6961 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
6976 assert((IsPPC64 || SVT != MVT::i64) &&
6977 "i64 should have been split for 32-bit codegen.");
6985 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6987 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6989 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
6997 return &PPC::VRRCRegClass;
7010 else if (Flags.isZExt())
7022 "Reg must be a valid argument register!");
7023 return LASize + 4 * (
Reg - PPC::R3);
7028 "Reg must be a valid argument register!");
7029 return LASize + 8 * (
Reg - PPC::X3);
7075SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7082 "Unexpected calling convention!");
7090 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7092 const bool IsPPC64 = Subtarget.isPPC64();
7093 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7099 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7100 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7104 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7105 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7106 uint64_t SaveStackPos = CCInfo.getStackSize();
7108 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7112 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7113 CCValAssign &VA = ArgLocs[
I++];
7119 bool ArgSignExt =
Ins[VA.
getValNo()].Flags.isSExt();
7131 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7133 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7139 MachinePointerInfo(),
Align(PtrByteSize));
7145 unsigned StoreSize =
7147 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7150 auto HandleMemLoc = [&]() {
7153 assert((ValSize <= LocSize) &&
7154 "Object size is larger than size of MemLoc");
7157 if (LocSize > ValSize)
7158 CurArgOffset += LocSize - ValSize;
7160 const bool IsImmutable =
7166 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7200 assert(isVarArg &&
"Only use custom memloc for vararg.");
7203 const unsigned OriginalValNo = VA.
getValNo();
7204 (void)OriginalValNo;
7206 auto HandleCustomVecRegLoc = [&]() {
7207 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7208 "Missing custom RegLoc.");
7211 "Unexpected Val type for custom RegLoc.");
7213 "ValNo mismatch between custom MemLoc and RegLoc.");
7217 Subtarget.hasVSX()));
7224 HandleCustomVecRegLoc();
7225 HandleCustomVecRegLoc();
7229 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7231 "Only 2 custom RegLocs expected for 64-bit codegen.");
7232 HandleCustomVecRegLoc();
7233 HandleCustomVecRegLoc();
7277 const unsigned Size =
7289 if (
Flags.isByVal()) {
7293 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7295 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7303 const TargetRegisterClass *RegClass =
7304 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7306 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7319 CopyFrom.
getValue(1), dl, CopyFrom,
7329 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7332 "RegLocs should be for ByVal argument.");
7334 const CCValAssign RL = ArgLocs[
I++];
7339 if (
Offset != StackSize) {
7341 "Expected MemLoc for remaining bytes.");
7342 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7356 Subtarget.hasVSX()));
7373 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7375 unsigned CallerReservedArea = std::max<unsigned>(
7376 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7382 CallerReservedArea =
7391 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7392 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7394 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7395 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7396 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7401 for (
unsigned GPRIndex =
7402 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7403 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7406 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7407 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7419 if (!MemOps.
empty())
7425SDValue PPCTargetLowering::LowerCall_AIX(
7438 "Unexpected calling convention!");
7440 if (CFlags.IsPatchPoint)
7443 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7447 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7454 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7455 const bool IsPPC64 = Subtarget.isPPC64();
7457 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7458 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7459 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7467 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7468 const unsigned NumBytes = std::max<unsigned>(
7469 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7485 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7486 const unsigned ValNo = ArgLocs[
I].getValNo();
7488 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7490 if (
Flags.isByVal()) {
7491 const unsigned ByValSize =
Flags.getByValSize();
7499 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7505 MachinePointerInfo(), VT);
7508 unsigned LoadOffset = 0;
7511 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7514 LoadOffset += PtrByteSize;
7515 const CCValAssign &ByValVA = ArgLocs[
I++];
7517 "Unexpected location for pass-by-value argument.");
7521 if (LoadOffset == ByValSize)
7525 assert(ArgLocs[
I].getValNo() == ValNo &&
7526 "Expected additional location for by-value argument.");
7528 if (ArgLocs[
I].isMemLoc()) {
7529 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7530 const CCValAssign &ByValVA = ArgLocs[
I++];
7531 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7534 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7540 CallSeqStart, MemcpyFlags, DAG, dl);
7549 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7550 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7551 "Unexpected register residue for by-value argument.");
7553 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7557 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7567 "Unexpected load emitted during handling of pass-by-value "
7575 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7580 const CCValAssign &ByValVA = ArgLocs[
I++];
7585 CCValAssign &VA = ArgLocs[
I++];
7610 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7616 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7618 const unsigned OriginalValNo = VA.
getValNo();
7620 unsigned LoadOffset = 0;
7621 auto HandleCustomVecRegLoc = [&]() {
7622 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7623 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7624 "Expected custom RegLoc.");
7625 CCValAssign RegVA = ArgLocs[
I++];
7627 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7633 LoadOffset += PtrByteSize;
7639 HandleCustomVecRegLoc();
7640 HandleCustomVecRegLoc();
7642 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7643 ArgLocs[
I].getValNo() == OriginalValNo) {
7645 "Only 2 custom RegLocs expected for 64-bit codegen.");
7646 HandleCustomVecRegLoc();
7647 HandleCustomVecRegLoc();
7658 DAG.
getStore(Chain, dl, Arg, PtrOff,
7660 Subtarget.getFrameLowering()->getStackAlign()));
7667 "Unexpected register handling for calling convention.");
7673 "Custom register handling only expected for VarArg.");
7678 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7682 else if (Arg.getValueType().getFixedSizeInBits() <
7690 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7691 "Unexpected custom register for argument!");
7692 CCValAssign &GPR1 = VA;
7701 CCValAssign &PeekArg = ArgLocs[
I];
7704 CCValAssign &GPR2 = ArgLocs[
I++];
7712 if (!MemOpChains.
empty())
7717 if (CFlags.IsIndirect) {
7718 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7719 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7720 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7721 const MVT PtrVT = Subtarget.getScalarIntVT();
7722 const unsigned TOCSaveOffset =
7723 Subtarget.getFrameLowering()->getTOCSaveOffset();
7738 for (
auto Reg : RegsToPass) {
7743 const int SPDiff = 0;
7744 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7745 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7753 const Type *RetTy)
const {
7755 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7756 return CCInfo.CheckReturn(
7771 CCInfo.AnalyzeReturn(Outs,
7780 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7781 CCValAssign &VA = RVLocs[i];
7784 SDValue Arg = OutVals[RealResIdx];
7799 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7800 bool isLittleEndian = Subtarget.isLittleEndian();
7803 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7807 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7822 RetOps.push_back(Glue);
7824 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7828PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7833 EVT IntVT =
Op.getValueType();
7837 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7841 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7853 bool isPPC64 = Subtarget.isPPC64();
7854 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7863 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7869 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7874 bool isPPC64 = Subtarget.isPPC64();
7879 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7885 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7895PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7897 bool isPPC64 = Subtarget.isPPC64();
7902 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7908 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
7931 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7933 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
7935 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
7936 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
7943 bool isPPC64 = Subtarget.isPPC64();
7953 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
7955 Op.getOperand(0),
Op.getOperand(1));
7961 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
7962 Op.getOperand(0),
Op.getOperand(1));
7966 if (
Op.getValueType().isVector())
7967 return LowerVectorLoad(
Op, DAG);
7969 assert(
Op.getValueType() == MVT::i1 &&
7970 "Custom lowering only for i1 loads");
7979 MachineMemOperand *MMO =
LD->getMemOperand();
7983 BasePtr, MVT::i8, MMO);
7991 if (
Op.getOperand(1).getValueType().isVector())
7992 return LowerVectorStore(
Op, DAG);
7994 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
7995 "Custom lowering only for i1 stores");
8005 MachineMemOperand *MMO =
ST->getMemOperand();
8014 assert(
Op.getValueType() == MVT::i1 &&
8015 "Custom lowering only for i1 results");
8043 EVT TrgVT =
Op.getValueType();
8067 if (SrcSize == 256) {
8078 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8084 SmallVector<int, 16> ShuffV;
8085 if (Subtarget.isLittleEndian())
8086 for (
unsigned i = 0; i < TrgNumElts; ++i)
8089 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8093 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8097 Op1 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op1);
8098 Op2 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op2);
8106 EVT ResVT =
Op.getValueType();
8107 EVT CmpVT =
Op.getOperand(0).getValueType();
8109 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8115 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8128 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8132 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8164 if (
LHS.getValueType() == MVT::f32)
8166 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8168 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8169 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8170 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), Sel1, FV);
8177 if (
LHS.getValueType() == MVT::f32)
8179 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8186 if (
LHS.getValueType() == MVT::f32)
8188 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8189 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), TV, FV);
8200 if (
Cmp.getValueType() == MVT::f32)
8201 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8202 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8204 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8205 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8206 DAG.
getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
8210 if (
Cmp.getValueType() == MVT::f32)
8211 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8212 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8216 if (
Cmp.getValueType() == MVT::f32)
8217 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8218 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8222 if (
Cmp.getValueType() == MVT::f32)
8223 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8224 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8228 if (
Cmp.getValueType() == MVT::f32)
8229 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8230 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8239 case PPCISD::FCTIDZ:
8240 return PPCISD::STRICT_FCTIDZ;
8241 case PPCISD::FCTIWZ:
8242 return PPCISD::STRICT_FCTIWZ;
8243 case PPCISD::FCTIDUZ:
8244 return PPCISD::STRICT_FCTIDUZ;
8245 case PPCISD::FCTIWUZ:
8246 return PPCISD::STRICT_FCTIWUZ;
8248 return PPCISD::STRICT_FCFID;
8249 case PPCISD::FCFIDU:
8250 return PPCISD::STRICT_FCFIDU;
8251 case PPCISD::FCFIDS:
8252 return PPCISD::STRICT_FCFIDS;
8253 case PPCISD::FCFIDUS:
8254 return PPCISD::STRICT_FCFIDUS;
8261 bool IsStrict =
Op->isStrictFPOpcode();
8270 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8272 MVT DestTy =
Op.getSimpleValueType();
8273 assert(Src.getValueType().isFloatingPoint() &&
8274 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8275 DestTy == MVT::i64) &&
8276 "Invalid FP_TO_INT types");
8277 if (Src.getValueType() == MVT::f32) {
8281 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8284 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
8286 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8292 Opc = IsSigned ? PPCISD::FCTIWZ
8293 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8296 assert((IsSigned || Subtarget.hasFPCVT()) &&
8297 "i64 FP_TO_UINT is supported only with FPCVT");
8298 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8300 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8312void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8314 const SDLoc &dl)
const {
8318 bool IsStrict =
Op->isStrictFPOpcode();
8321 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8322 (IsSigned || Subtarget.hasFPCVT());
8325 MachinePointerInfo MPI =
8333 Alignment =
Align(4);
8334 MachineMemOperand *MMO =
8340 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8344 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8345 !Subtarget.isLittleEndian()) {
8354 RLI.Alignment = Alignment;
8362 const SDLoc &dl)
const {
8365 if (
Op->isStrictFPOpcode())
8372 const SDLoc &dl)
const {
8373 bool IsStrict =
Op->isStrictFPOpcode();
8376 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8377 EVT SrcVT = Src.getValueType();
8378 EVT DstVT =
Op.getValueType();
8381 if (SrcVT == MVT::f128)
8382 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8386 if (SrcVT == MVT::ppcf128) {
8387 if (DstVT == MVT::i32) {
8392 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8403 {Op.getOperand(0), Lo, Hi}, Flags);
8406 {Res.getValue(1), Res}, Flags);
8412 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8436 {Chain, Src, FltOfs}, Flags);
8440 {Chain, Val}, Flags);
8443 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8461 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8462 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8465 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8467 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8468 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8479bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8484 if (
Op->isStrictFPOpcode())
8489 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8493 Op.getOperand(0).getValueType())) {
8495 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8500 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8501 LD->isNonTemporal())
8503 if (
LD->getMemoryVT() != MemVT)
8513 RLI.Ptr =
LD->getBasePtr();
8514 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8516 "Non-pre-inc AM on PPC?");
8521 RLI.Chain =
LD->getChain();
8522 RLI.MPI =
LD->getPointerInfo();
8523 RLI.IsDereferenceable =
LD->isDereferenceable();
8524 RLI.IsInvariant =
LD->isInvariant();
8525 RLI.Alignment =
LD->getAlign();
8526 RLI.AAInfo =
LD->getAAInfo();
8527 RLI.Ranges =
LD->getRanges();
8529 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8536bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8537 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8544 if (!Subtarget.hasP9Vector() &&
8548 for (SDUse &Use : Origin->
uses()) {
8551 if (
Use.getResNo() != 0)
8578 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8579 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8580 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8581 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8582 if (
Op->isStrictFPOpcode()) {
8584 Chain =
Op.getOperand(0);
8586 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8588 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8596 const SDLoc &dl)
const {
8597 assert((
Op.getValueType() == MVT::f32 ||
8598 Op.getValueType() == MVT::f64) &&
8599 "Invalid floating point type as target of conversion");
8600 assert(Subtarget.hasFPCVT() &&
8601 "Int to FP conversions with direct moves require FPCVT");
8602 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8603 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8606 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8625 for (
unsigned i = 1; i < NumConcat; ++i)
8632 const SDLoc &dl)
const {
8633 bool IsStrict =
Op->isStrictFPOpcode();
8634 unsigned Opc =
Op.getOpcode();
8635 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8638 "Unexpected conversion type");
8639 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8640 "Supports conversions to v2f64/v4f32 only.");
8644 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8647 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8652 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8654 SmallVector<int, 16> ShuffV;
8655 for (
unsigned i = 0; i < WideNumElts; ++i)
8658 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8659 int SaveElts = FourEltRes ? 4 : 2;
8660 if (Subtarget.isLittleEndian())
8661 for (
int i = 0; i < SaveElts; i++)
8662 ShuffV[i * Stride] = i;
8664 for (
int i = 1; i <= SaveElts; i++)
8665 ShuffV[i * Stride - 1] = i - 1;
8673 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8674 EVT ExtVT = Src.getValueType();
8675 if (Subtarget.hasP9Altivec())
8682 Extend = DAG.
getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
8686 {Op.getOperand(0), Extend}, Flags);
8688 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8696 bool IsStrict =
Op->isStrictFPOpcode();
8697 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8702 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8704 EVT InVT = Src.getValueType();
8705 EVT OutVT =
Op.getValueType();
8708 return LowerINT_TO_FPVector(
Op, DAG, dl);
8711 if (
Op.getValueType() == MVT::f128)
8712 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8715 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8718 if (Src.getValueType() == MVT::i1) {
8730 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8731 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8732 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8734 assert((IsSigned || Subtarget.hasFPCVT()) &&
8735 "UINT_TO_FP is supported only with FPCVT");
8737 if (Src.getValueType() == MVT::i64) {
8752 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8753 !
Op->getFlags().hasApproximateFuncs()) {
8793 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8794 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8795 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8798 }
else if (Subtarget.hasLFIWAX() &&
8799 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8800 MachineMemOperand *MMO =
8802 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8806 Ops, MVT::i32, MMO);
8809 }
else if (Subtarget.hasFPCVT() &&
8810 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8811 MachineMemOperand *MMO =
8813 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8817 Ops, MVT::i32, MMO);
8820 }
else if (((Subtarget.hasLFIWAX() &&
8822 (Subtarget.hasFPCVT() &&
8837 "Expected an i32 store");
8843 RLI.Alignment =
Align(4);
8845 MachineMemOperand *MMO =
8847 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8850 PPCISD::LFIWZX : PPCISD::LFIWAX,
8851 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8852 Ops, MVT::i32, MMO);
8853 Chain =
Bits.getValue(1);
8855 Bits = DAG.
getNode(ISD::BITCAST, dl, MVT::f64, SINT);
8861 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8865 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8874 assert(Src.getValueType() == MVT::i32 &&
8875 "Unhandled INT_TO_FP type in custom expander!");
8885 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8888 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8898 "Expected an i32 store");
8904 RLI.Alignment =
Align(4);
8907 MachineMemOperand *MMO =
8909 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8915 if (ReusingLoad && RLI.ResChain) {
8919 assert(Subtarget.isPPC64() &&
8920 "i32->FP without LFIWAX supported only on PPC64");
8929 Chain, dl, Ext64, FIdx,
8935 MVT::f64, dl, Chain, FIdx,
8944 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8948 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
8965 uint64_t
Mode = CVal->getZExtValue();
8966 assert(
Mode < 4 &&
"Unsupported rounding mode!");
8967 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
8968 if (Subtarget.isISA3_0())
8971 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
8972 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
8975 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
8976 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
8978 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
8996 if (!Subtarget.isISA3_0()) {
8997 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9001 if (Subtarget.isPPC64()) {
9002 if (Subtarget.isISA3_0()) {
9007 PPC::RLDIMI, Dl, MVT::i64,
9008 {DAG.
getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
9012 NewFPSCR =
SDValue(InsertRN, 0);
9014 NewFPSCR = DAG.
getNode(ISD::BITCAST, Dl, MVT::f64, NewFPSCR);
9019 SDValue Addr = Subtarget.isLittleEndian()
9023 if (Subtarget.isISA3_0()) {
9024 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9026 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9028 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9031 PPC::RLWIMI, Dl, MVT::i32,
9032 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9033 DAG.getTargetConstant(30, Dl, MVT::i32),
9034 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9036 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9039 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9042 if (Subtarget.isISA3_0())
9048 PPC::MTFSF, Dl, MVT::Other,
9076 EVT VT =
Op.getValueType();
9081 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9087 DAG.
getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
9092 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9096 "Stack slot adjustment is valid only on big endian subtargets!");
9099 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9126 EVT VT =
Op.getValueType();
9130 VT ==
Op.getOperand(1).getValueType() &&
9150 SDValue OutOps[] = { OutLo, OutHi };
9155 EVT VT =
Op.getValueType();
9159 VT ==
Op.getOperand(1).getValueType() &&
9179 SDValue OutOps[] = { OutLo, OutHi };
9185 EVT VT =
Op.getValueType();
9188 VT ==
Op.getOperand(1).getValueType() &&
9208 SDValue OutOps[] = { OutLo, OutHi };
9215 EVT VT =
Op.getValueType();
9222 EVT AmtVT =
Z.getValueType();
9232 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9233 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9245 static const MVT VTys[] = {
9246 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9249 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9252 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9257 EVT CanonicalVT = VTys[SplatSize-1];
9270 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9271 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9280 EVT DestVT = MVT::Other) {
9281 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9290 EVT DestVT = MVT::Other) {
9293 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9305 for (
unsigned i = 0; i != 16; ++i)
9308 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9326 EVT VecVT = V->getValueType(0);
9327 bool RightType = VecVT == MVT::v2f64 ||
9328 (HasP8Vector && VecVT == MVT::v4f32) ||
9329 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9333 bool IsSplat =
true;
9334 bool IsLoad =
false;
9340 if (V->isConstant())
9342 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9343 if (V->getOperand(i).isUndef())
9347 if (V->getOperand(i).getOpcode() == ISD::LOAD ||
9349 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9351 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9353 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
9357 if (V->getOperand(i) != Op0 ||
9358 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9361 return !(IsSplat && IsLoad);
9371 (
Op.getValueType() != MVT::f128))
9376 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9379 if (!Subtarget.isLittleEndian())
9382 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9387 while (InputLoad->
getOpcode() == ISD::BITCAST)
9390 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9391 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9394 if (InputLoad->
getOpcode() != ISD::LOAD)
9404 APFloat APFloatToConvert = ArgAPFloat;
9405 bool LosesInfo =
true;
9410 ArgAPFloat = APFloatToConvert;
9432 APFloat APFloatToConvert = ArgAPFloat;
9433 bool LosesInfo =
true;
9437 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9446 EVT Ty =
Op->getValueType(0);
9449 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9458 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9462 if (Ty == MVT::v2i64) {
9465 if (MemVT == MVT::i32) {
9467 Opcode = PPCISD::ZEXT_LD_SPLAT;
9469 Opcode = PPCISD::SEXT_LD_SPLAT;
9477 bool IsLittleEndian) {
9483 APInt ConstValue(VTSize, 0);
9487 unsigned BitPos = 0;
9495 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9496 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9500 for (
unsigned J = 0; J < 16; ++J) {
9502 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9504 if (ExtractValue == 0xFF)
9519 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9521 if (Subtarget.hasP10Vector()) {
9522 APInt BitMask(32, 0);
9528 BitMask != 0 && BitMask != 0xffff) {
9530 MachineSDNode *MSDNode =
9536 SDV = DAG.
getNode(ISD::BITCAST, dl, DVT, SDV);
9542 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9546 APInt APSplatBits, APSplatUndef;
9547 unsigned SplatBitSize;
9549 bool BVNIsConstantSplat =
9551 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9557 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9558 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9561 if ((
Op->getValueType(0) == MVT::v2f64) &&
9564 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9580 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9586 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9594 bool IsSplat64 =
false;
9595 uint64_t SplatBits = 0;
9596 int32_t SextVal = 0;
9597 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9599 if (SplatBitSize <= 32) {
9601 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9602 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9603 bool P9Vector = Subtarget.hasP9Vector();
9604 int32_t
Hi = P9Vector ? 127 : 15;
9605 int32_t
Lo = P9Vector ? -128 : -16;
9606 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9607 SextVal =
static_cast<int32_t
>(SplatBits);
9611 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9612 unsigned NewOpcode = PPCISD::LD_SPLAT;
9618 const SDValue *InputLoad = &
Op.getOperand(0);
9623 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9624 unsigned ElementSize =
9625 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9627 assert(((ElementSize == 2 * MemorySize)
9628 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9629 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9630 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9631 "Unmatched element size and opcode!\n");
9636 unsigned NumUsesOfInputLD = 128 / ElementSize;
9638 if (BVInOp.isUndef())
9653 if (NumUsesOfInputLD == 1 &&
9654 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9655 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9656 Subtarget.hasLFIWAX()))
9664 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9665 Subtarget.isISA3_1() && ElementSize <= 16)
9668 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9670 Subtarget.hasVSX()) {
9677 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9678 LD->getMemoryVT(),
LD->getMemOperand());
9690 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9692 Subtarget.hasP8Vector()))
9698 unsigned SplatSize = SplatBitSize / 8;
9703 if (SplatBits == 0) {
9705 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9707 Op = DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Z);
9717 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9719 Op.getValueType(), DAG, dl);
9721 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9726 if (Subtarget.hasP9Vector() && SplatSize == 1)
9732 if (SextVal >= -16 && SextVal <= 15) {
9735 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9745 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9751 switch (SplatSize) {
9755 IID = Intrinsic::ppc_altivec_vupklsb;
9759 IID = Intrinsic::ppc_altivec_vextsb2w;
9763 IID = Intrinsic::ppc_altivec_vextsb2d;
9770 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9779 if (SextVal >= -32 && SextVal <= 31) {
9784 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9785 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9788 if (VT ==
Op.getValueType())
9791 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), RetVal);
9797 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9807 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9811 static const signed char SplatCsts[] = {
9812 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9813 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9816 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9819 int i = SplatCsts[idx];
9823 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9826 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9828 static const unsigned IIDs[] = {
9829 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9830 Intrinsic::ppc_altivec_vslw
9833 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9837 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9839 static const unsigned IIDs[] = {
9840 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9841 Intrinsic::ppc_altivec_vsrw
9844 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9848 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9849 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9851 static const unsigned IIDs[] = {
9852 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9853 Intrinsic::ppc_altivec_vrlw
9856 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9860 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9862 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9866 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9868 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9872 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9874 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9887 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9888 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9889 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9905 if (LHSID == (1*9+2)*9+3)
return LHS;
9906 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9918 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9919 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9920 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9921 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9924 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9925 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9926 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9927 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9930 for (
unsigned i = 0; i != 16; ++i)
9931 ShufIdxs[i] = (i&3)+0;
9934 for (
unsigned i = 0; i != 16; ++i)
9935 ShufIdxs[i] = (i&3)+4;
9938 for (
unsigned i = 0; i != 16; ++i)
9939 ShufIdxs[i] = (i&3)+8;
9942 for (
unsigned i = 0; i != 16; ++i)
9943 ShufIdxs[i] = (i&3)+12;
9953 OpLHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpLHS);
9954 OpRHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpRHS);
9956 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9964 const unsigned BytesInVector = 16;
9965 bool IsLE = Subtarget.isLittleEndian();
9969 unsigned ShiftElts = 0, InsertAtByte = 0;
9973 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9974 0, 15, 14, 13, 12, 11, 10, 9};
9975 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9976 1, 2, 3, 4, 5, 6, 7, 8};
9978 ArrayRef<int>
Mask =
N->getMask();
9979 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9991 bool FoundCandidate =
false;
9995 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9998 for (
unsigned i = 0; i < BytesInVector; ++i) {
9999 unsigned CurrentElement =
Mask[i];
10002 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10005 bool OtherElementsInOrder =
true;
10008 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10015 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10016 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10017 OtherElementsInOrder =
false;
10024 if (OtherElementsInOrder) {
10031 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10032 : BigEndianShifts[CurrentElement & 0xF];
10033 Swap = CurrentElement < BytesInVector;
10035 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10036 FoundCandidate =
true;
10041 if (!FoundCandidate)
10051 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10053 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10056 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10065 const unsigned NumHalfWords = 8;
10066 const unsigned BytesInVector = NumHalfWords * 2;
10071 bool IsLE = Subtarget.isLittleEndian();
10075 unsigned ShiftElts = 0, InsertAtByte = 0;
10079 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10080 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10083 uint32_t OriginalOrderLow = 0x1234567;
10084 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10087 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10088 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10105 bool FoundCandidate =
false;
10108 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10109 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10111 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10112 uint32_t TargetOrder = 0x0;
10119 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10120 TargetOrder = OriginalOrderLow;
10124 if (MaskOneElt == VINSERTHSrcElem &&
10125 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10126 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10127 FoundCandidate =
true;
10133 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10135 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10137 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10138 : BigEndianShifts[MaskOneElt & 0x7];
10139 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10140 Swap = MaskOneElt < NumHalfWords;
10141 FoundCandidate =
true;
10147 if (!FoundCandidate)
10159 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10164 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10169 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10182 auto ShuffleMask = SVN->
getMask();
10197 ShuffleMask = CommutedSV->
getMask();
10206 APInt APSplatValue, APSplatUndef;
10207 unsigned SplatBitSize;
10210 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10222 bool IsLE = Subtarget.isLittleEndian();
10223 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10224 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10225 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10227 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10228 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10229 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10237 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10238 SplatVal |= (SplatVal << SplatBitSize);
10241 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10243 return DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8, SplatNode);
10252 assert(
Op.getValueType() == MVT::v1i128 &&
10253 "Only set v1i128 as custom, other type shouldn't reach here!");
10258 if (SHLAmt % 8 == 0) {
10259 std::array<int, 16>
Mask;
10260 std::iota(
Mask.begin(),
Mask.end(), 0);
10261 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10265 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, Shuffle);
10273 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, OROp);
10290 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10295 V1 =
Op.getOperand(0);
10296 V2 =
Op.getOperand(1);
10298 EVT VT =
Op.getValueType();
10299 bool isLittleEndian = Subtarget.isLittleEndian();
10301 unsigned ShiftElts, InsertAtByte;
10307 bool IsPermutedLoad =
false;
10309 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10319 if (IsPermutedLoad) {
10320 assert((isLittleEndian || IsFourByte) &&
10321 "Unexpected size for permuted load on big endian target");
10322 SplatIdx += IsFourByte ? 2 : 1;
10323 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10324 "Splat of a value outside of the loaded memory");
10329 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10332 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10334 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10338 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10351 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10354 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10363 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10366 if (Subtarget.hasP9Vector() &&
10376 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10380 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10384 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10387 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10389 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10390 return SplatInsertNode;
10393 if (Subtarget.hasP9Altivec()) {
10395 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10398 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10402 if (Subtarget.hasVSX() &&
10408 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, V2.
isUndef() ? V1 : V2);
10410 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10412 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
10415 if (Subtarget.hasVSX() &&
10421 DAG.
getNode(ISD::BITCAST, dl, MVT::v2i64, V2.isUndef() ? V1 : V2);
10423 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10425 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
10428 if (Subtarget.hasP9Vector()) {
10432 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveHWord);
10436 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveWord);
10440 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveDWord);
10444 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveQWord);
10448 if (Subtarget.hasVSX()) {
10455 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8,
Splat);
10461 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10462 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Swap);
10469 if (V2.isUndef()) {
10482 (Subtarget.hasP8Altivec() && (
10493 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10503 (Subtarget.hasP8Altivec() && (
10511 ArrayRef<int> PermMask = SVOp->
getMask();
10514 unsigned PFIndexes[4];
10515 bool isFourElementShuffle =
true;
10516 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10518 unsigned EltNo = 8;
10519 for (
unsigned j = 0;
j != 4; ++
j) {
10520 if (PermMask[i * 4 + j] < 0)
10523 unsigned ByteSource = PermMask[i * 4 +
j];
10524 if ((ByteSource & 3) != j) {
10525 isFourElementShuffle =
false;
10530 EltNo = ByteSource / 4;
10531 }
else if (EltNo != ByteSource / 4) {
10532 isFourElementShuffle =
false;
10536 PFIndexes[i] = EltNo;
10544 if (isFourElementShuffle) {
10546 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10547 PFIndexes[2] * 9 + PFIndexes[3];
10550 unsigned Cost = (PFEntry >> 30);
10570 if (V2.isUndef()) V2 = V1;
10572 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10578 unsigned Opcode = PPCISD::VPERM;
10581 bool NeedSwap =
false;
10582 bool isLittleEndian = Subtarget.isLittleEndian();
10583 bool isPPC64 = Subtarget.isPPC64();
10585 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10587 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10588 "XXPERM instead\n");
10589 Opcode = PPCISD::XXPERM;
10597 NeedSwap = !NeedSwap;
10632 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10634 if (V1HasXXSWAPD) {
10637 else if (SrcElt < 16)
10640 if (V2HasXXSWAPD) {
10643 else if (SrcElt > 15)
10652 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10653 if (isLittleEndian)
10655 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10658 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10661 if (V1HasXXSWAPD) {
10665 if (V2HasXXSWAPD) {
10670 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10671 if (ValType != MVT::v2f64)
10677 ShufflesHandledWithVPERM++;
10681 if (Opcode == PPCISD::XXPERM) {
10682 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10684 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10687 dbgs() <<
"With the following permute control vector:\n";
10691 if (Opcode == PPCISD::XXPERM)
10692 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10696 if (isLittleEndian)
10702 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10714 switch (IntrinsicID) {
10718 case Intrinsic::ppc_altivec_vcmpbfp_p:
10722 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10726 case Intrinsic::ppc_altivec_vcmpequb_p:
10730 case Intrinsic::ppc_altivec_vcmpequh_p:
10734 case Intrinsic::ppc_altivec_vcmpequw_p:
10738 case Intrinsic::ppc_altivec_vcmpequd_p:
10739 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10745 case Intrinsic::ppc_altivec_vcmpneb_p:
10746 case Intrinsic::ppc_altivec_vcmpneh_p:
10747 case Intrinsic::ppc_altivec_vcmpnew_p:
10748 case Intrinsic::ppc_altivec_vcmpnezb_p:
10749 case Intrinsic::ppc_altivec_vcmpnezh_p:
10750 case Intrinsic::ppc_altivec_vcmpnezw_p:
10751 if (Subtarget.hasP9Altivec()) {
10752 switch (IntrinsicID) {
10755 case Intrinsic::ppc_altivec_vcmpneb_p:
10758 case Intrinsic::ppc_altivec_vcmpneh_p:
10761 case Intrinsic::ppc_altivec_vcmpnew_p:
10764 case Intrinsic::ppc_altivec_vcmpnezb_p:
10767 case Intrinsic::ppc_altivec_vcmpnezh_p:
10770 case Intrinsic::ppc_altivec_vcmpnezw_p:
10778 case Intrinsic::ppc_altivec_vcmpgefp_p:
10782 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10786 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10790 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10794 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10798 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10799 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10805 case Intrinsic::ppc_altivec_vcmpgtub_p:
10809 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10813 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10817 case Intrinsic::ppc_altivec_vcmpgtud_p:
10818 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10825 case Intrinsic::ppc_altivec_vcmpequq:
10826 case Intrinsic::ppc_altivec_vcmpgtsq:
10827 case Intrinsic::ppc_altivec_vcmpgtuq:
10828 if (!Subtarget.isISA3_1())
10830 switch (IntrinsicID) {
10833 case Intrinsic::ppc_altivec_vcmpequq:
10836 case Intrinsic::ppc_altivec_vcmpgtsq:
10839 case Intrinsic::ppc_altivec_vcmpgtuq:
10846 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10847 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10848 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10849 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10850 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10851 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10852 if (Subtarget.hasVSX()) {
10853 switch (IntrinsicID) {
10854 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10857 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10860 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10863 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10866 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10869 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10879 case Intrinsic::ppc_altivec_vcmpbfp:
10882 case Intrinsic::ppc_altivec_vcmpeqfp:
10885 case Intrinsic::ppc_altivec_vcmpequb:
10888 case Intrinsic::ppc_altivec_vcmpequh:
10891 case Intrinsic::ppc_altivec_vcmpequw:
10894 case Intrinsic::ppc_altivec_vcmpequd:
10895 if (Subtarget.hasP8Altivec())
10900 case Intrinsic::ppc_altivec_vcmpneb:
10901 case Intrinsic::ppc_altivec_vcmpneh:
10902 case Intrinsic::ppc_altivec_vcmpnew:
10903 case Intrinsic::ppc_altivec_vcmpnezb:
10904 case Intrinsic::ppc_altivec_vcmpnezh:
10905 case Intrinsic::ppc_altivec_vcmpnezw:
10906 if (Subtarget.hasP9Altivec())
10907 switch (IntrinsicID) {
10910 case Intrinsic::ppc_altivec_vcmpneb:
10913 case Intrinsic::ppc_altivec_vcmpneh:
10916 case Intrinsic::ppc_altivec_vcmpnew:
10919 case Intrinsic::ppc_altivec_vcmpnezb:
10922 case Intrinsic::ppc_altivec_vcmpnezh:
10925 case Intrinsic::ppc_altivec_vcmpnezw:
10932 case Intrinsic::ppc_altivec_vcmpgefp:
10935 case Intrinsic::ppc_altivec_vcmpgtfp:
10938 case Intrinsic::ppc_altivec_vcmpgtsb:
10941 case Intrinsic::ppc_altivec_vcmpgtsh:
10944 case Intrinsic::ppc_altivec_vcmpgtsw:
10947 case Intrinsic::ppc_altivec_vcmpgtsd:
10948 if (Subtarget.hasP8Altivec())
10953 case Intrinsic::ppc_altivec_vcmpgtub:
10956 case Intrinsic::ppc_altivec_vcmpgtuh:
10959 case Intrinsic::ppc_altivec_vcmpgtuw:
10962 case Intrinsic::ppc_altivec_vcmpgtud:
10963 if (Subtarget.hasP8Altivec())
10968 case Intrinsic::ppc_altivec_vcmpequq_p:
10969 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10970 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10971 if (!Subtarget.isISA3_1())
10973 switch (IntrinsicID) {
10976 case Intrinsic::ppc_altivec_vcmpequq_p:
10979 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10982 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10996 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11000 switch (IntrinsicID) {
11001 case Intrinsic::thread_pointer:
11003 if (Subtarget.isPPC64())
11007 case Intrinsic::ppc_rldimi: {
11008 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11010 APInt
Mask =
Op.getConstantOperandAPInt(4);
11012 return Op.getOperand(2);
11013 if (
Mask.isAllOnes())
11015 uint64_t SH =
Op.getConstantOperandVal(3);
11016 unsigned MB = 0, ME = 0;
11020 if (ME < 63 - SH) {
11023 }
else if (ME > 63 - SH) {
11029 {Op.getOperand(2), Src,
11030 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11031 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11035 case Intrinsic::ppc_rlwimi: {
11036 APInt
Mask =
Op.getConstantOperandAPInt(4);
11038 return Op.getOperand(2);
11039 if (
Mask.isAllOnes())
11042 unsigned MB = 0, ME = 0;
11046 PPC::RLWIMI, dl, MVT::i32,
11047 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11048 DAG.getTargetConstant(MB, dl, MVT::i32),
11049 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11053 case Intrinsic::ppc_rlwnm: {
11054 if (
Op.getConstantOperandVal(3) == 0)
11056 unsigned MB = 0, ME = 0;
11061 {Op.getOperand(1), Op.getOperand(2),
11062 DAG.getTargetConstant(MB, dl, MVT::i32),
11063 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11067 case Intrinsic::ppc_mma_disassemble_acc: {
11068 if (Subtarget.isISAFuture()) {
11069 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11080 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11081 Subtarget.isLittleEndian() ? Value2 :
Value,
11082 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11086 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11087 Subtarget.isLittleEndian() ? Value2 :
Value,
11088 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11092 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11093 Subtarget.isLittleEndian() ?
Value : Value2,
11094 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11098 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11099 Subtarget.isLittleEndian() ?
Value : Value2,
11100 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11107 case Intrinsic::ppc_vsx_disassemble_pair: {
11110 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11112 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11115 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11117 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11118 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11126 case Intrinsic::ppc_mma_build_dmr: {
11129 for (
int i = 1; i < 9; i += 2) {
11132 if (
Hi->getOpcode() == ISD::LOAD)
11134 if (
Lo->getOpcode() == ISD::LOAD)
11137 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11144 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11145 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11147 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11148 "Specify P of 0 or 1 for lower or upper 512 bytes");
11149 unsigned HiLo = Idx->getSExtValue();
11153 Opcode = PPC::DMXXEXTFDMR512;
11154 Subx = PPC::sub_wacc_lo;
11156 Opcode = PPC::DMXXEXTFDMR512_HI;
11157 Subx = PPC::sub_wacc_hi;
11160 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11164 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11168 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11169 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11171 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11172 "Specify a dmr row pair 0-3");
11173 unsigned IdxVal = Idx->getSExtValue();
11177 Subx = PPC::sub_dmrrowp0;
11180 Subx = PPC::sub_dmrrowp1;
11183 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11186 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11190 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11196 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11200 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11201 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11203 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11204 "Specify P of 0 or 1 for lower or upper 512 bytes");
11205 unsigned HiLo = Idx->getSExtValue();
11209 Opcode = PPC::DMXXINSTDMR512;
11210 Subx = PPC::sub_wacc_lo;
11212 Opcode = PPC::DMXXINSTDMR512_HI;
11213 Subx = PPC::sub_wacc_hi;
11223 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11224 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11226 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11227 "Specify a dmr row pair 0-3");
11228 unsigned IdxVal = Idx->getSExtValue();
11232 Subx = PPC::sub_dmrrowp0;
11235 Subx = PPC::sub_dmrrowp1;
11238 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11241 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11250 Op.getOperand(1), DMRRowp,
SubReg),
11254 case Intrinsic::ppc_mma_xxmfacc:
11255 case Intrinsic::ppc_mma_xxmtacc: {
11257 if (!Subtarget.isISAFuture())
11268 case Intrinsic::ppc_unpack_longdouble: {
11270 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11271 "Argument of long double unpack must be 0 or 1!");
11274 Idx->getValueType(0)));
11277 case Intrinsic::ppc_compare_exp_lt:
11278 case Intrinsic::ppc_compare_exp_gt:
11279 case Intrinsic::ppc_compare_exp_eq:
11280 case Intrinsic::ppc_compare_exp_uo: {
11282 switch (IntrinsicID) {
11283 case Intrinsic::ppc_compare_exp_lt:
11286 case Intrinsic::ppc_compare_exp_gt:
11289 case Intrinsic::ppc_compare_exp_eq:
11292 case Intrinsic::ppc_compare_exp_uo:
11298 PPC::SELECT_CC_I4, dl, MVT::i32,
11299 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11300 Op.getOperand(1), Op.getOperand(2)),
11302 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11303 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11306 case Intrinsic::ppc_test_data_class: {
11307 EVT OpVT =
Op.getOperand(1).getValueType();
11308 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11309 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11313 PPC::SELECT_CC_I4, dl, MVT::i32,
11314 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11317 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11318 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11321 case Intrinsic::ppc_fnmsub: {
11322 EVT VT =
Op.getOperand(1).getValueType();
11323 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11327 DAG.
getNode(ISD::FNEG, dl, VT,
Op.getOperand(3))));
11328 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11329 Op.getOperand(2),
Op.getOperand(3));
11331 case Intrinsic::ppc_convert_f128_to_ppcf128:
11332 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11333 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11334 ? RTLIB::CONVERT_PPCF128_F128
11335 : RTLIB::CONVERT_F128_PPCF128;
11337 std::pair<SDValue, SDValue>
Result =
11338 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11342 case Intrinsic::ppc_maxfe:
11343 case Intrinsic::ppc_maxfl:
11344 case Intrinsic::ppc_maxfs:
11345 case Intrinsic::ppc_minfe:
11346 case Intrinsic::ppc_minfl:
11347 case Intrinsic::ppc_minfs: {
11348 EVT VT =
Op.getValueType();
11351 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11352 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11355 if (IntrinsicID == Intrinsic::ppc_minfe ||
11356 IntrinsicID == Intrinsic::ppc_minfl ||
11357 IntrinsicID == Intrinsic::ppc_minfs)
11378 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11379 Op.getOperand(1),
Op.getOperand(2),
11381 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Tmp);
11390 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11398 switch (
Op.getConstantOperandVal(1)) {
11403 Bitx = PPC::sub_eq;
11404 SetOp = PPCISD::SETBC;
11409 Bitx = PPC::sub_eq;
11410 SetOp = PPCISD::SETBCR;
11415 Bitx = PPC::sub_lt;
11416 SetOp = PPCISD::SETBC;
11421 Bitx = PPC::sub_lt;
11422 SetOp = PPCISD::SETBCR;
11427 if (Subtarget.isISA3_1()) {
11432 CR6Reg, SubRegIdx, GlueOp),
11434 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11462 switch (
Op.getConstantOperandVal(ArgStart)) {
11463 case Intrinsic::ppc_cfence: {
11464 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11465 SDValue Val =
Op.getOperand(ArgStart + 1);
11467 if (Ty == MVT::i128) {
11472 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11475 Opcode,
DL, MVT::Other,
11480 case Intrinsic::ppc_mma_disassemble_dmr: {
11482 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11493 if (!Subtarget.isPPC64())
11501 int VectorIndex = 0;
11502 if (Subtarget.isLittleEndian())
11513 assert(
Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
11514 "Expecting an atomic compare-and-swap here.");
11517 EVT MemVT = AtomicNode->getMemoryVT();
11535 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11536 Ops.push_back(AtomicNode->getOperand(i));
11538 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11539 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11541 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11548 EVT MemVT =
N->getMemoryVT();
11550 "Expect quadword atomic operations");
11552 unsigned Opc =
N->getOpcode();
11554 case ISD::ATOMIC_LOAD: {
11557 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11560 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11561 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11562 Ops.push_back(
N->getOperand(
I));
11564 Ops, MemVT,
N->getMemOperand());
11571 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11575 case ISD::ATOMIC_STORE: {
11578 SDVTList Tys = DAG.
getVTList(MVT::Other);
11581 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11587 Ops.push_back(ValLo);
11588 Ops.push_back(ValHi);
11589 Ops.push_back(
N->getOperand(2));
11591 N->getMemOperand());
11603 enum DataClassMask {
11605 DC_NEG_INF = 1 << 4,
11606 DC_POS_INF = 1 << 5,
11607 DC_NEG_ZERO = 1 << 2,
11608 DC_POS_ZERO = 1 << 3,
11609 DC_NEG_SUBNORM = 1,
11610 DC_POS_SUBNORM = 1 << 1,
11613 EVT VT =
Op.getValueType();
11615 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11616 : VT == MVT::f64 ? PPC::XSTSTDCDP
11627 return DAG.
getNOT(Dl, Rev, MVT::i1);
11634 TestOp, Dl, MVT::i32,
11636 DC_NEG_ZERO | DC_POS_ZERO |
11637 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11643 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11649 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11654 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11667 bool IsQuiet = Mask &
fcQNan;
11673 if (VT == MVT::f128) {
11677 QuietMask = 0x8000;
11678 }
else if (VT == MVT::f64) {
11679 if (Subtarget.isPPC64()) {
11690 QuietMask = 0x80000;
11691 }
else if (VT == MVT::f32) {
11693 QuietMask = 0x400000;
11709 unsigned NativeMask = 0;
11711 NativeMask |= DC_NAN;
11713 NativeMask |= DC_NEG_INF;
11715 NativeMask |= DC_POS_INF;
11717 NativeMask |= DC_NEG_ZERO;
11719 NativeMask |= DC_POS_ZERO;
11721 NativeMask |= DC_NEG_SUBNORM;
11723 NativeMask |= DC_POS_SUBNORM;
11726 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11728 TestOp, Dl, MVT::i32,
11737 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11739 uint64_t RHSC =
Op.getConstantOperandVal(1);
11742 if (
LHS.getValueType() == MVT::ppcf128) {
11766 bool Future = Subtarget.isISAFuture();
11769 "Mask predication not supported");
11772 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11773 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11777 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11780 VPLD->getMemoryVT(), VPLD->getMemOperand());
11787 "Mask predication not supported");
11792 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11793 bool Future = Subtarget.isISAFuture();
11794 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11797 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11798 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, VPST->getOperand(1)),
11800 SDVTList Tys = DAG.
getVTList(MVT::Other);
11803 VPST->getMemoryVT(), VPST->getMemOperand());
11814 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11816 int64_t
IntVal =
Op.getConstantOperandVal(0);
11817 if (IntVal >= -16 && IntVal <= 15)
11823 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11824 Op.getValueType() == MVT::v4i32 && Op0.
getOpcode() == ISD::LOAD &&
11828 MachineMemOperand *MMO =
11830 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11833 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
11837 return Bits.getValue(0);
11853 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11858 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11865 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11866 MachinePointerInfo());
11873 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
11879 "Should only be called for ISD::INSERT_VECTOR_ELT");
11883 EVT VT =
Op.getValueType();
11888 if (VT == MVT::v2f64 &&
C)
11891 if (Subtarget.hasP9Vector()) {
11900 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
11906 BitcastLoad,
Op.getOperand(2));
11907 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11911 if (Subtarget.isISA3_1()) {
11912 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
11916 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11917 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11927 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11930 unsigned InsertAtElement =
C->getZExtValue();
11931 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11932 if (Subtarget.isLittleEndian()) {
11933 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11935 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
11947 EVT VT =
Op.getValueType();
11948 bool IsV1024i1 = VT == MVT::v1024i1;
11949 bool IsV2048i1 = VT == MVT::v2048i1;
11953 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
11955 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
11956 "Dense Math support required.");
11957 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
11966 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
11967 MachineMemOperand *NewMMO =
11975 DAG.
getVTList(MVT::v256i1, MVT::Other),
11976 LoadOps, MVT::v256i1, NewMMO);
11981 if (Subtarget.isLittleEndian()) {
11982 std::reverse(Loads.
begin(), Loads.
end());
11983 std::reverse(LoadChains.
begin(), LoadChains.
end());
11992 Loads[2], Loads[3]),
12008 Loads[4], Loads[5]),
12011 Loads[6], Loads[7]),
12013 const SDValue Dmr1Ops[] = {RC, Dmr1Lo, LoSub, Dmr1Hi, HiSub};
12015 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Dmr1Ops), 0);
12021 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12024 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12037 Pairs[2], Pairs[3]),
12043 {RC, Lo, LoSub, Hi, HiSub}),
12053 EVT VT =
Op.getValueType();
12055 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12056 return LowerDMFVectorLoad(
Op, DAG);
12058 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12064 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12065 "Type unsupported without MMA");
12066 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12067 "Type unsupported without paired vector support");
12072 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12074 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12083 if (Subtarget.isLittleEndian()) {
12084 std::reverse(Loads.
begin(), Loads.
end());
12085 std::reverse(LoadChains.
begin(), LoadChains.
end());
12089 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12105 bool IsV1024i1 = VT == MVT::v1024i1;
12106 bool IsV2048i1 = VT == MVT::v2048i1;
12110 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12112 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12113 "Dense Math support required.");
12114 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12116 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12119 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12124 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12128 MachineSDNode *ExtNode =
12132 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12138 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12144 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12150 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12155 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12160 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12165 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12169 MachineSDNode *ExtNode =
12170 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12174 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12177 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12181 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12186 if (Subtarget.isLittleEndian())
12187 std::reverse(Values.
begin(), Values.
end());
12189 SDVTList Tys = DAG.
getVTList(MVT::Other);
12191 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12195 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12196 MachineMemOperand *NewMMO =
12203 Ops[2] = Values[Idx];
12205 MVT::v256i1, NewMMO);
12221 EVT StoreVT =
Value.getValueType();
12223 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12224 return LowerDMFVectorStore(
Op, DAG);
12226 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12232 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12233 "Type unsupported without MMA");
12234 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12235 "Type unsupported without paired vector support");
12238 unsigned NumVecs = 2;
12239 if (StoreVT == MVT::v512i1) {
12240 if (Subtarget.isISAFuture()) {
12241 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12243 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12246 Value2 =
SDValue(ExtNode, 1);
12251 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12252 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12254 if (Subtarget.isISAFuture()) {
12255 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12256 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12257 Idx > 1 ? Value2 :
Value,
12260 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12264 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12278 if (
Op.getValueType() == MVT::v4i32) {
12290 RHSSwap = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHSSwap);
12295 LHS,
RHS, DAG, dl, MVT::v4i32);
12298 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12303 }
else if (
Op.getValueType() == MVT::v16i8) {
12305 bool isLittleEndian = Subtarget.isLittleEndian();
12309 LHS,
RHS, DAG, dl, MVT::v8i16);
12310 EvenParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, EvenParts);
12314 LHS,
RHS, DAG, dl, MVT::v8i16);
12315 OddParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OddParts);
12322 for (
unsigned i = 0; i != 8; ++i) {
12323 if (isLittleEndian) {
12325 Ops[i*2+1] = 2*i+16;
12328 Ops[i*2+1] = 2*i+1+16;
12331 if (isLittleEndian)
12341 bool IsStrict =
Op->isStrictFPOpcode();
12342 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12343 !Subtarget.hasP9Vector())
12352 assert(
Op.getOpcode() == ISD::FP_EXTEND &&
12353 "Should only be called for ISD::FP_EXTEND");
12357 if (
Op.getValueType() != MVT::v2f64 ||
12358 Op.getOperand(0).getValueType() != MVT::v2f32)
12370 "Node should have 2 operands with second one being a constant!");
12382 int DWord = Idx >> 1;
12385 if (Subtarget.isLittleEndian())
12388 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12402 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12404 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12405 LD->getMemoryVT(),
LD->getMemOperand());
12410 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12415 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12417 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12418 LD->getMemoryVT(),
LD->getMemOperand());
12419 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12430 if (STI.useCRBits())
12447 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12448 if (STI.useCRBits())
12456 SDNode *
N =
Op.getNode();
12457 EVT VT =
N->getValueType(0);
12458 EVT CarryType =
N->getValueType(1);
12459 unsigned Opc =
N->getOpcode();
12461 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12463 N->getOperand(0),
N->getOperand(1));
12475 SDNode *
N =
Op.getNode();
12476 unsigned Opc =
N->getOpcode();
12477 EVT VT =
N->getValueType(0);
12478 EVT CarryType =
N->getValueType(1);
12479 SDValue CarryOp =
N->getOperand(2);
12481 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12487 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12501 EVT VT =
Op.getNode()->getValueType(0);
12527 EVT VT =
Op.getNode()->getValueType(0);
12556 EVT OpVT =
A.getValueType();
12557 EVT ResVT =
Op.getValueType();
12563 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12581 switch (
Op.getOpcode()) {
12584 case ISD::FPOW:
return lowerPow(
Op, DAG);
12585 case ISD::FSIN:
return lowerSin(
Op, DAG);
12586 case ISD::FCOS:
return lowerCos(
Op, DAG);
12587 case ISD::FLOG:
return lowerLog(
Op, DAG);
12588 case ISD::FLOG10:
return lowerLog10(
Op, DAG);
12589 case ISD::FEXP:
return lowerExp(
Op, DAG);
12598 case ISD::INIT_TRAMPOLINE:
return LowerINIT_TRAMPOLINE(
Op, DAG);
12599 case ISD::ADJUST_TRAMPOLINE:
return LowerADJUST_TRAMPOLINE(
Op, DAG);
12601 return LowerSSUBO(
Op, DAG);
12603 return LowerSADDO(
Op, DAG);
12605 case ISD::INLINEASM:
12606 case ISD::INLINEASM_BR:
return LowerINLINEASM(
Op, DAG);
12608 case ISD::VASTART:
return LowerVASTART(
Op, DAG);
12609 case ISD::VAARG:
return LowerVAARG(
Op, DAG);
12610 case ISD::VACOPY:
return LowerVACOPY(
Op, DAG);
12612 case ISD::STACKRESTORE:
return LowerSTACKRESTORE(
Op, DAG);
12613 case ISD::DYNAMIC_STACKALLOC:
return LowerDYNAMIC_STACKALLOC(
Op, DAG);
12614 case ISD::GET_DYNAMIC_AREA_OFFSET:
12615 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12622 case ISD::LOAD:
return LowerLOAD(
Op, DAG);
12623 case ISD::STORE:
return LowerSTORE(
Op, DAG);
12635 case ISD::SET_ROUNDING:
12636 return LowerSET_ROUNDING(
Op, DAG);
12643 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12644 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12653 case ISD::FP_EXTEND:
return LowerFP_EXTEND(
Op, DAG);
12656 return LowerFP_ROUND(
Op, DAG);
12662 case ISD::BITCAST:
return LowerBITCAST(
Op, DAG);
12669 return LowerINTRINSIC_VOID(
Op, DAG);
12671 return LowerBSWAP(
Op, DAG);
12672 case ISD::ATOMIC_CMP_SWAP:
12673 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12674 case ISD::ATOMIC_STORE:
12675 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12677 return LowerIS_FPCLASS(
Op, DAG);
12680 return LowerADDSUBO(
Op, DAG);
12683 return LowerADDSUBO_CARRY(
Op, DAG);
12685 return LowerUCMP(
Op, DAG);
12691 if (
Op->getFlags().hasNoFPExcept())
12695 return LowerVP_LOAD(
Op, DAG);
12696 case ISD::VP_STORE:
12697 return LowerVP_STORE(
Op, DAG);
12705 switch (
N->getOpcode()) {
12707 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12708 case ISD::ATOMIC_LOAD: {
12714 case ISD::READCYCLECOUNTER: {
12724 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12727 assert(
N->getValueType(0) == MVT::i1 &&
12728 "Unexpected result type for CTR decrement intrinsic");
12730 N->getValueType(0));
12740 switch (
N->getConstantOperandVal(0)) {
12741 case Intrinsic::ppc_pack_longdouble:
12743 N->getOperand(2),
N->getOperand(1)));
12745 case Intrinsic::ppc_maxfe:
12746 case Intrinsic::ppc_minfe:
12747 case Intrinsic::ppc_fnmsub:
12748 case Intrinsic::ppc_convert_f128_to_ppcf128:
12755 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12758 EVT VT =
N->getValueType(0);
12760 if (VT == MVT::i64) {
12773 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12777 Results.push_back(LoweredValue);
12778 if (
N->isStrictFPOpcode())
12783 if (!
N->getValueType(0).isVector())
12803 case ISD::FP_EXTEND:
12816 return Builder.CreateIntrinsic(Id, {});
12822 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12824 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12825 "Only 8/16/32/64-bit atomic loads supported");
12831 IntID = Intrinsic::ppc_lbarx;
12832 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12835 IntID = Intrinsic::ppc_lharx;
12836 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12839 IntID = Intrinsic::ppc_lwarx;
12842 IntID = Intrinsic::ppc_ldarx;
12846 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12848 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12859 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12860 "Only 8/16/32/64-bit atomic loads supported");
12866 IntID = Intrinsic::ppc_stbcx;
12867 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12870 IntID = Intrinsic::ppc_sthcx;
12871 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12874 IntID = Intrinsic::ppc_stwcx;
12877 IntID = Intrinsic::ppc_stdcx;
12881 if (SZ == 8 || SZ == 16)
12882 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
12884 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
12886 return Builder.CreateXor(
Call, Builder.getInt32(1));
12909 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
12919 unsigned AtomicSize,
12920 unsigned BinOpcode,
12921 unsigned CmpOpcode,
12922 unsigned CmpPred)
const {
12926 auto LoadMnemonic = PPC::LDARX;
12927 auto StoreMnemonic = PPC::STDCX;
12928 switch (AtomicSize) {
12932 LoadMnemonic = PPC::LBARX;
12933 StoreMnemonic = PPC::STBCX;
12934 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12937 LoadMnemonic = PPC::LHARX;
12938 StoreMnemonic = PPC::STHCX;
12939 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12942 LoadMnemonic = PPC::LWARX;
12943 StoreMnemonic = PPC::STWCX;
12946 LoadMnemonic = PPC::LDARX;
12947 StoreMnemonic = PPC::STDCX;
12963 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12965 F->insert(It, loopMBB);
12967 F->insert(It, loop2MBB);
12968 F->insert(It, exitMBB);
12974 Register TmpReg = (!BinOpcode) ? incr :
12975 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
12976 : &PPC::GPRCRegClass);
13001 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13006 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13008 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13009 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13010 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13040 switch(
MI.getOpcode()) {
13044 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13045 &
MI.getMF()->getRegInfo());
13069 case PPC::EXTSB8_32_64:
13070 case PPC::EXTSB8_rec:
13071 case PPC::EXTSB_rec:
13074 case PPC::EXTSH8_32_64:
13075 case PPC::EXTSH8_rec:
13076 case PPC::EXTSH_rec:
13078 case PPC::EXTSWSLI:
13079 case PPC::EXTSWSLI_32_64:
13080 case PPC::EXTSWSLI_32_64_rec:
13081 case PPC::EXTSWSLI_rec:
13082 case PPC::EXTSW_32:
13083 case PPC::EXTSW_32_64:
13084 case PPC::EXTSW_32_64_rec:
13085 case PPC::EXTSW_rec:
13088 case PPC::SRAWI_rec:
13089 case PPC::SRAW_rec:
13098 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13108 bool IsSignExtended =
13111 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13112 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13113 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13114 .
addReg(
MI.getOperand(3).getReg());
13115 MI.getOperand(3).setReg(ValueReg);
13119 if (Subtarget.hasPartwordAtomics())
13127 bool is64bit = Subtarget.isPPC64();
13128 bool isLittleEndian = Subtarget.isLittleEndian();
13129 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13140 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13142 F->insert(It, loopMBB);
13144 F->insert(It, loop2MBB);
13145 F->insert(It, exitMBB);
13151 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13154 Register PtrReg = RegInfo.createVirtualRegister(RC);
13155 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13157 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13158 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13159 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13160 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13161 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13162 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13163 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13164 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13165 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13166 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13169 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13196 if (ptrA != ZeroReg) {
13197 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13198 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13206 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13207 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13210 .
addImm(is8bit ? 28 : 27);
13211 if (!isLittleEndian)
13212 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13214 .
addImm(is8bit ? 24 : 16);
13216 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13221 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13231 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13235 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13240 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13244 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13247 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13254 Register SReg = RegInfo.createVirtualRegister(GPRC);
13255 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13259 unsigned ValueReg = SReg;
13260 unsigned CmpReg = Incr2Reg;
13261 if (CmpOpcode == PPC::CMPW) {
13262 ValueReg = RegInfo.createVirtualRegister(GPRC);
13263 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13266 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13267 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13269 ValueReg = ValueSReg;
13301 .
addImm(is8bit ? 24 : 16)
13322 Register DstReg =
MI.getOperand(0).getReg();
13324 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13325 Register mainDstReg =
MRI.createVirtualRegister(RC);
13326 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13329 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13330 "Invalid Pointer Size!");
13378 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13379 Register BufReg =
MI.getOperand(1).getReg();
13381 if (Subtarget.is64BitELFABI()) {
13394 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13396 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13399 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13422 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13425 if (Subtarget.isPPC64()) {
13443 TII->get(PPC::PHI), DstReg)
13447 MI.eraseFromParent();
13461 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13462 "Invalid Pointer Size!");
13465 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13468 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13469 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13483 Register BufReg =
MI.getOperand(0).getReg();
13488 if (PVT == MVT::i64) {
13500 if (PVT == MVT::i64) {
13512 if (PVT == MVT::i64) {
13524 if (PVT == MVT::i64) {
13536 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13546 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13549 MI.eraseFromParent();
13565 "Unexpected stack alignment");
13569 unsigned StackProbeSize =
13572 StackProbeSize &= ~(StackAlign - 1);
13573 return StackProbeSize ? StackProbeSize : StackAlign;
13585 const bool isPPC64 = Subtarget.isPPC64();
13617 MF->
insert(MBBIter, TestMBB);
13618 MF->
insert(MBBIter, BlockMBB);
13619 MF->
insert(MBBIter, TailMBB);
13624 Register DstReg =
MI.getOperand(0).getReg();
13625 Register NegSizeReg =
MI.getOperand(1).getReg();
13627 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13628 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13629 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13635 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13637 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13643 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13644 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13646 .
addDef(ActualNegSizeReg)
13648 .
add(
MI.getOperand(2))
13649 .
add(
MI.getOperand(3));
13655 .
addReg(ActualNegSizeReg);
13658 int64_t NegProbeSize = -(int64_t)ProbeSize;
13660 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13662 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13664 .
addImm(NegProbeSize >> 16);
13668 .
addImm(NegProbeSize & 0xFFFF);
13675 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13677 .
addReg(ActualNegSizeReg)
13679 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13683 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13686 .
addReg(ActualNegSizeReg);
13695 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13696 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13721 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13723 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13724 MaxCallFrameSizeReg)
13725 .
add(
MI.getOperand(2))
13726 .
add(
MI.getOperand(3));
13727 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13729 .
addReg(MaxCallFrameSizeReg);
13735 MBB->addSuccessor(TestMBB);
13738 MI.eraseFromParent();
13740 ++NumDynamicAllocaProbed;
13745 switch (
MI.getOpcode()) {
13746 case PPC::SELECT_CC_I4:
13747 case PPC::SELECT_CC_I8:
13748 case PPC::SELECT_CC_F4:
13749 case PPC::SELECT_CC_F8:
13750 case PPC::SELECT_CC_F16:
13751 case PPC::SELECT_CC_VRRC:
13752 case PPC::SELECT_CC_VSFRC:
13753 case PPC::SELECT_CC_VSSRC:
13754 case PPC::SELECT_CC_VSRC:
13755 case PPC::SELECT_CC_SPE4:
13756 case PPC::SELECT_CC_SPE:
13764 switch (
MI.getOpcode()) {
13765 case PPC::SELECT_I4:
13766 case PPC::SELECT_I8:
13767 case PPC::SELECT_F4:
13768 case PPC::SELECT_F8:
13769 case PPC::SELECT_F16:
13770 case PPC::SELECT_SPE:
13771 case PPC::SELECT_SPE4:
13772 case PPC::SELECT_VRRC:
13773 case PPC::SELECT_VSFRC:
13774 case PPC::SELECT_VSSRC:
13775 case PPC::SELECT_VSRC:
13785 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13786 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13787 if (Subtarget.is64BitELFABI() &&
13788 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13789 !Subtarget.isUsingPCRelativeCalls()) {
13801 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13802 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13804 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13805 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13819 if (Subtarget.hasISEL() &&
13820 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13821 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13822 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13824 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13825 MI.getOpcode() == PPC::SELECT_CC_I8)
13826 Cond.push_back(
MI.getOperand(4));
13829 Cond.push_back(
MI.getOperand(1));
13832 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13833 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13849 F->insert(It, copy0MBB);
13850 F->insert(It, sinkMBB);
13859 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13874 .
addReg(
MI.getOperand(1).getReg())
13877 unsigned SelectPred =
MI.getOperand(4).getImm();
13880 .
addReg(
MI.getOperand(1).getReg())
13897 .
addReg(
MI.getOperand(3).getReg())
13899 .
addReg(
MI.getOperand(2).getReg())
13901 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13917 F->insert(It, readMBB);
13918 F->insert(It, sinkMBB);
13929 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13937 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13939 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13949 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13951 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13953 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13955 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13958 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13960 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13962 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13964 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13967 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13969 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13971 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13973 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13976 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13978 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13980 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13982 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13985 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13987 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13989 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13991 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13994 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13996 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13998 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14000 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14003 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14005 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14007 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14009 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14012 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14014 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14016 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14018 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14021 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14023 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14025 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14027 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14030 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14032 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14034 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14036 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14039 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14041 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14043 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14045 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14047 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14048 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14049 (Subtarget.hasPartwordAtomics() &&
14050 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14051 (Subtarget.hasPartwordAtomics() &&
14052 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14053 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14055 auto LoadMnemonic = PPC::LDARX;
14056 auto StoreMnemonic = PPC::STDCX;
14057 switch (
MI.getOpcode()) {
14060 case PPC::ATOMIC_CMP_SWAP_I8:
14061 LoadMnemonic = PPC::LBARX;
14062 StoreMnemonic = PPC::STBCX;
14063 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14065 case PPC::ATOMIC_CMP_SWAP_I16:
14066 LoadMnemonic = PPC::LHARX;
14067 StoreMnemonic = PPC::STHCX;
14068 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14070 case PPC::ATOMIC_CMP_SWAP_I32:
14071 LoadMnemonic = PPC::LWARX;
14072 StoreMnemonic = PPC::STWCX;
14074 case PPC::ATOMIC_CMP_SWAP_I64:
14075 LoadMnemonic = PPC::LDARX;
14076 StoreMnemonic = PPC::STDCX;
14083 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14084 Register oldval =
MI.getOperand(3).getReg();
14085 Register newval =
MI.getOperand(4).getReg();
14091 F->insert(It, loop1MBB);
14092 F->insert(It, loop2MBB);
14093 F->insert(It, exitMBB);
14114 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14140 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14141 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14145 bool is64bit = Subtarget.isPPC64();
14146 bool isLittleEndian = Subtarget.isLittleEndian();
14147 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14152 Register oldval =
MI.getOperand(3).getReg();
14153 Register newval =
MI.getOperand(4).getReg();
14159 F->insert(It, loop1MBB);
14160 F->insert(It, loop2MBB);
14161 F->insert(It, exitMBB);
14168 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14171 Register PtrReg = RegInfo.createVirtualRegister(RC);
14172 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14174 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14175 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14176 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14177 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14178 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14179 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14180 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14181 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14182 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14183 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14184 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14186 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14187 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14188 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14219 if (ptrA != ZeroReg) {
14220 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14221 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14230 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14231 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
14234 .
addImm(is8bit ? 28 : 27);
14235 if (!isLittleEndian)
14236 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14238 .
addImm(is8bit ? 24 : 16);
14240 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14245 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14250 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14253 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14260 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14264 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14267 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14270 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14275 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14292 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14316 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14326 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14341 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14349 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14350 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14351 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14352 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14353 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14354 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14357 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14358 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14361 Register Dest = RegInfo.createVirtualRegister(
14362 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14366 .
addReg(
MI.getOperand(1).getReg())
14369 MI.getOperand(0).getReg())
14370 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14371 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14374 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14377 MI.getOperand(0).getReg())
14379 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14381 unsigned Imm =
MI.getOperand(1).getImm();
14384 MI.getOperand(0).getReg())
14386 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14388 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14391 if (
MRI.use_empty(OldFPSCRReg))
14392 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14394 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14405 unsigned Mode =
MI.getOperand(1).getImm();
14406 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14410 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14413 }
else if (
MI.getOpcode() == PPC::SETRND) {
14421 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14422 if (Subtarget.hasDirectMove()) {
14423 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14427 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14430 if (RC == &PPC::F8RCRegClass) {
14432 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14433 "Unsupported RegClass.");
14435 StoreOp = PPC::STFD;
14439 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14440 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14441 "Unsupported RegClass.");
14474 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14477 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14489 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14491 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14493 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14494 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14499 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14500 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14505 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14506 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14512 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14513 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14522 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14526 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14527 if (
MRI.use_empty(OldFPSCRReg))
14528 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14530 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14533 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14539 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14540 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14542 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14549 .
addUse(Src, 0, PPC::sub_gp8_x1);
14552 .
addUse(Src, 0, PPC::sub_gp8_x0);
14553 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14554 MI.getOpcode() == PPC::STQX_PSEUDO) {
14560 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14566 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14567 :
TII->get(PPC::STQ))
14575 MI.eraseFromParent();
14588 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14591 return RefinementSteps;
14597 EVT VT =
Op.getValueType();
14600 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14624PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14627 EVT VT =
Op.getValueType();
14628 if (VT != MVT::f64 &&
14629 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14632 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14636 int Enabled,
int &RefinementSteps,
14637 bool &UseOneConstNR,
14638 bool Reciprocal)
const {
14640 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14641 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14642 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14643 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14649 UseOneConstNR = !Subtarget.needsTwoConstNR();
14650 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14657 int &RefinementSteps)
const {
14659 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14660 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14661 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14662 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14665 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14681 switch (Subtarget.getCPUDirective()) {
14708 unsigned Bytes,
int Dist,
14722 if (FS != BFS || FS != (
int)Bytes)
return false;
14727 int64_t Offset1 = 0, Offset2 = 0;
14730 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14740 if (isGA1 && isGA2 && GV1 == GV2)
14741 return Offset1 == (Offset2 + Dist*Bytes);
14748 unsigned Bytes,
int Dist,
14751 EVT VT = LS->getMemoryVT();
14758 switch (
N->getConstantOperandVal(1)) {
14759 default:
return false;
14760 case Intrinsic::ppc_altivec_lvx:
14761 case Intrinsic::ppc_altivec_lvxl:
14762 case Intrinsic::ppc_vsx_lxvw4x:
14763 case Intrinsic::ppc_vsx_lxvw4x_be:
14766 case Intrinsic::ppc_vsx_lxvd2x:
14767 case Intrinsic::ppc_vsx_lxvd2x_be:
14770 case Intrinsic::ppc_altivec_lvebx:
14773 case Intrinsic::ppc_altivec_lvehx:
14776 case Intrinsic::ppc_altivec_lvewx:
14786 switch (
N->getConstantOperandVal(1)) {
14787 default:
return false;
14788 case Intrinsic::ppc_altivec_stvx:
14789 case Intrinsic::ppc_altivec_stvxl:
14790 case Intrinsic::ppc_vsx_stxvw4x:
14793 case Intrinsic::ppc_vsx_stxvd2x:
14796 case Intrinsic::ppc_vsx_stxvw4x_be:
14799 case Intrinsic::ppc_vsx_stxvd2x_be:
14802 case Intrinsic::ppc_altivec_stvebx:
14805 case Intrinsic::ppc_altivec_stvehx:
14808 case Intrinsic::ppc_altivec_stvewx:
14825 SDValue Chain = LD->getChain();
14826 EVT VT = LD->getMemoryVT();
14835 while (!Queue.empty()) {
14836 SDNode *ChainNext = Queue.pop_back_val();
14837 if (!Visited.
insert(ChainNext).second)
14844 if (!Visited.
count(ChainLD->getChain().getNode()))
14845 Queue.push_back(ChainLD->getChain().getNode());
14847 for (
const SDUse &O : ChainNext->
ops())
14848 if (!Visited.
count(O.getNode()))
14849 Queue.push_back(O.getNode());
14851 LoadRoots.
insert(ChainNext);
14862 for (
SDNode *
I : LoadRoots) {
14863 Queue.push_back(
I);
14865 while (!Queue.empty()) {
14866 SDNode *LoadRoot = Queue.pop_back_val();
14867 if (!Visited.
insert(LoadRoot).second)
14879 Queue.push_back(U);
14912 auto Final = Shifted;
14923 DAGCombinerInfo &DCI)
const {
14926 SelectionDAG &DAG = DCI.DAG;
14931 if (!DCI.isAfterLegalizeDAG())
14936 for (
const SDNode *U :
N->users())
14941 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14945 if (OpSize <
Size) {
14963 DAGCombinerInfo &DCI)
const {
14964 SelectionDAG &DAG = DCI.DAG;
14967 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14978 N->getValueType(0) != MVT::i1)
14981 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14982 N->getOperand(0).getValueType() != MVT::i64)
14992 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15003 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15026 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15027 N->getOperand(0).getOpcode() !=
ISD::OR &&
15028 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15038 N->getOperand(1).getOpcode() !=
ISD::AND &&
15039 N->getOperand(1).getOpcode() !=
ISD::OR &&
15040 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15051 SmallPtrSet<SDNode *, 16> Visited;
15053 for (
unsigned i = 0; i < 2; ++i) {
15057 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15069 while (!BinOps.
empty()) {
15077 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15111 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15115 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15116 if (User !=
N && !Visited.
count(User))
15125 if (
User->getOperand(0) == Inputs[i])
15128 if (
User->getOperand(0) == Inputs[i] ||
15129 User->getOperand(1) == Inputs[i])
15135 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15136 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15137 if (User !=
N && !Visited.
count(User))
15146 if (
User->getOperand(0) == PromOps[i])
15149 if (
User->getOperand(0) == PromOps[i] ||
15150 User->getOperand(1) == PromOps[i])
15157 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15166 std::list<HandleSDNode> PromOpHandles;
15167 for (
auto &PromOp : PromOps)
15168 PromOpHandles.emplace_back(PromOp);
15175 while (!PromOpHandles.empty()) {
15176 SDValue PromOp = PromOpHandles.back().getValue();
15177 PromOpHandles.pop_back();
15186 PromOpHandles.emplace_front(PromOp);
15200 default:
C = 0;
break;
15213 PromOpHandles.emplace_front(PromOp);
15220 for (
unsigned i = 0; i < 2; ++i)
15230 return N->getOperand(0);
15238 DAGCombinerInfo &DCI)
const {
15239 SelectionDAG &DAG = DCI.DAG;
15256 if (
N->getValueType(0) != MVT::i32 &&
15257 N->getValueType(0) != MVT::i64)
15260 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15261 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15264 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15265 N->getOperand(0).getOpcode() !=
ISD::OR &&
15266 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15273 SmallPtrSet<SDNode *, 16> Visited;
15277 while (!BinOps.
empty()) {
15285 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15311 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15316 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15321 if (User !=
N && !Visited.
count(User))
15327 if (
User->getOperand(0) == Inputs[i])
15328 SelectTruncOp[0].
insert(std::make_pair(User,
15329 User->getOperand(0).getValueType()));
15331 if (
User->getOperand(0) == Inputs[i])
15332 SelectTruncOp[0].
insert(std::make_pair(User,
15333 User->getOperand(0).getValueType()));
15334 if (
User->getOperand(1) == Inputs[i])
15335 SelectTruncOp[1].
insert(std::make_pair(User,
15336 User->getOperand(1).getValueType()));
15341 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15343 if (User !=
N && !Visited.
count(User))
15349 if (
User->getOperand(0) == PromOps[i])
15350 SelectTruncOp[0].
insert(std::make_pair(User,
15351 User->getOperand(0).getValueType()));
15353 if (
User->getOperand(0) == PromOps[i])
15354 SelectTruncOp[0].
insert(std::make_pair(User,
15355 User->getOperand(0).getValueType()));
15356 if (
User->getOperand(1) == PromOps[i])
15357 SelectTruncOp[1].
insert(std::make_pair(User,
15358 User->getOperand(1).getValueType()));
15363 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15364 bool ReallyNeedsExt =
false;
15368 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15373 Inputs[i].getOperand(0).getValueSizeInBits();
15374 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15379 OpBits-PromBits))) ||
15382 (OpBits-(PromBits-1)))) {
15383 ReallyNeedsExt =
true;
15391 std::list<HandleSDNode> PromOpHandles;
15392 for (
auto &PromOp : PromOps)
15393 PromOpHandles.emplace_back(PromOp);
15397 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15404 SDValue InSrc = Inputs[i].getOperand(0);
15422 while (!PromOpHandles.empty()) {
15424 PromOpHandles.pop_back();
15428 default:
C = 0;
break;
15441 PromOpHandles.emplace_front(PromOp);
15451 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15453 PromOpHandles.emplace_front(PromOp);
15461 for (
unsigned i = 0; i < 2; ++i) {
15479 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15480 if (SI0 != SelectTruncOp[0].
end())
15482 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15483 if (SI1 != SelectTruncOp[1].
end())
15492 if (!ReallyNeedsExt)
15493 return N->getOperand(0);
15500 N->getValueSizeInBits(0), PromBits),
15501 dl,
N->getValueType(0)));
15504 "Invalid extension type");
15507 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15517 auto isValidForConvert = [](
SDValue &Operand) {
15536 if (LoadNode->isVolatile())
15557 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15567 "CC mus be ISD::SETNE or ISD::SETEQ");
15569 auto getV16i8Load = [&](
const SDValue &Operand) {
15573 assert(Operand.
getOpcode() == ISD::LOAD &&
"Must be LoadSDNode here.");
15576 return DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15577 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15616 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15617 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15620 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15623 IntrID, CRSel, LHSVec, RHSVec);
15626 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15632 DAGCombinerInfo &DCI)
const {
15634 "Should be called with a SETCC node");
15651 SelectionDAG &DAG = DCI.DAG;
15652 EVT VT =
N->getValueType(0);
15653 EVT OpVT =
LHS.getValueType();
15675 return DAGCombineTruncBoolExt(
N, DCI);
15682 Op.getValueType() == MVT::f64;
15694combineElementTruncationToVectorTruncation(
SDNode *
N,
15695 DAGCombinerInfo &DCI)
const {
15697 "Should be called with a BUILD_VECTOR node");
15699 SelectionDAG &DAG = DCI.DAG;
15702 SDValue FirstInput =
N->getOperand(0);
15704 "The input operand must be an fp-to-int conversion.");
15709 if (FirstConversion == PPCISD::FCTIDZ ||
15710 FirstConversion == PPCISD::FCTIDUZ ||
15711 FirstConversion == PPCISD::FCTIWZ ||
15712 FirstConversion == PPCISD::FCTIWUZ) {
15713 bool IsSplat =
true;
15714 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
15715 FirstConversion == PPCISD::FCTIWUZ;
15718 EVT TargetVT =
N->getValueType(0);
15719 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15720 SDValue NextOp =
N->getOperand(i);
15721 if (NextOp.
getOpcode() != PPCISD::MFVSR)
15724 if (NextConversion != FirstConversion)
15732 if (
N->getOperand(i) != FirstInput)
15743 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15744 SDValue In =
N->getOperand(i).getOperand(0);
15754 Ops.push_back(Trunc);
15757 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
15761 if (FirstConversion == PPCISD::FCTIDZ ||
15762 FirstConversion == PPCISD::FCTIWZ)
15767 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15769 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15787 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
15791 if (FullVal == BasePattern)
15792 return std::make_tuple(Uim,
uint8_t{0});
15795 if (FullVal ==
APInt(128, 1))
15796 return std::make_tuple(Uim,
uint8_t{127});
15798 return std::nullopt;
15818 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
15822 EVT VT =
Op.getValueType();
15823 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
15837 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
15847 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
15851 uint64_t ElemValue =
C->getZExtValue();
15855 ElemValue &= ((1ULL << ElemBits) - 1);
15859 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
15862 APInt ElemAPInt(128, ElemValue);
15863 ElemAPInt <<= BitPos;
15866 FullVal |= ElemAPInt;
15873 const auto &[Uim, ShiftAmount] = *UIMOpt;
15877 if (ShiftAmount == 0) {
15882 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
15883 LxvkqInstr.
dump());
15887 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
15899 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
15902 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
15918 "Should be called with a BUILD_VECTOR node");
15923 if (!
N->getValueType(0).getVectorElementType().isByteSized())
15926 bool InputsAreConsecutiveLoads =
true;
15927 bool InputsAreReverseConsecutive =
true;
15928 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
15929 SDValue FirstInput =
N->getOperand(0);
15930 bool IsRoundOfExtLoad =
false;
15939 if ((!IsRoundOfExtLoad && FirstInput.
getOpcode() != ISD::LOAD) ||
15940 N->getNumOperands() == 1)
15943 if (!IsRoundOfExtLoad)
15948 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
15950 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
15953 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
15955 if (NextInput.
getOpcode() != ISD::LOAD)
15959 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
15970 InputsAreConsecutiveLoads =
false;
15972 InputsAreReverseConsecutive =
false;
15975 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15980 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15981 "The loads cannot be both consecutive and reverse consecutive.");
15985 if (InputsAreConsecutiveLoads) {
15986 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
15990 ReturnSDVal = WideLoad;
15991 }
else if (InputsAreReverseConsecutive) {
15993 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
15998 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16006 for (
auto *LD : InputLoads)
16008 return ReturnSDVal;
16019 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16025 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16027 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16029 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16030 CorrectElems = CorrectElems >> 8;
16031 Elems = Elems >> 8;
16038 EVT VT =
N->getValueType(0);
16042 Input.getValueType().getVectorElementType(),
16076 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16102 Elems = Elems << 8;
16111 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16112 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16119 int TgtElemArrayIdx;
16120 int InputSize =
Input.getValueType().getScalarSizeInBits();
16121 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16122 if (InputSize + OutputSize == 40)
16123 TgtElemArrayIdx = 0;
16124 else if (InputSize + OutputSize == 72)
16125 TgtElemArrayIdx = 1;
16126 else if (InputSize + OutputSize == 48)
16127 TgtElemArrayIdx = 2;
16128 else if (InputSize + OutputSize == 80)
16129 TgtElemArrayIdx = 3;
16130 else if (InputSize + OutputSize == 96)
16131 TgtElemArrayIdx = 4;
16135 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16137 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16138 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16139 if (Elems != CorrectElems) {
16155 if (
N->getValueType(0) != MVT::v1i128)
16158 SDValue Operand =
N->getOperand(0);
16165 EVT MemoryType = LD->getMemoryVT();
16169 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16170 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16173 if (!ValidLDType ||
16179 LD->getChain(), LD->getBasePtr(),
16183 DAG.
getVTList(MVT::v1i128, MVT::Other),
16184 LoadOps, MemoryType, LD->getMemOperand());
16188 DAGCombinerInfo &DCI)
const {
16190 "Should be called with a BUILD_VECTOR node");
16192 SelectionDAG &DAG = DCI.DAG;
16195 if (!Subtarget.hasVSX())
16202 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16203 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16218 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16227 if (Subtarget.isISA3_1()) {
16233 if (
N->getValueType(0) != MVT::v2f64)
16244 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16255 if (!Ext1Op || !Ext2Op)
16264 if (FirstElem == 0 && SecondElem == 1)
16265 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16266 else if (FirstElem == 2 && SecondElem == 3)
16267 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16273 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16274 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16279 DAGCombinerInfo &DCI)
const {
16282 "Need an int -> FP conversion node here");
16287 SelectionDAG &DAG = DCI.DAG;
16293 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16295 if (!
Op.getOperand(0).getValueType().isSimple())
16297 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16298 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16301 SDValue FirstOperand(
Op.getOperand(0));
16302 bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
16303 (FirstOperand.getValueType() == MVT::i8 ||
16304 FirstOperand.getValueType() == MVT::i16);
16305 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16307 bool DstDouble =
Op.getValueType() == MVT::f64;
16308 unsigned ConvOp =
Signed ?
16309 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16310 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16315 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16318 Ops, MVT::i8, LDN->getMemOperand());
16323 SDValue ExtOps[] = { Ld, WidthConst };
16325 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16327 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16335 if (
Op.getOperand(0).getValueType() == MVT::i32)
16339 "UINT_TO_FP is supported only with FPCVT");
16343 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16348 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16355 Subtarget.hasFPCVT()) ||
16357 SDValue Src =
Op.getOperand(0).getOperand(0);
16358 if (Src.getValueType() == MVT::f32) {
16359 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
16360 DCI.AddToWorklist(Src.getNode());
16361 }
else if (Src.getValueType() != MVT::f64) {
16373 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16376 DCI.AddToWorklist(
FP.getNode());
16400 switch (
N->getOpcode()) {
16405 Chain = LD->getChain();
16406 Base = LD->getBasePtr();
16407 MMO = LD->getMemOperand();
16426 MVT VecTy =
N->getValueType(0).getSimpleVT();
16434 Chain = Load.getValue(1);
16436 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16440 if (VecTy != MVT::v2f64) {
16467 switch (
N->getOpcode()) {
16472 Chain = ST->getChain();
16473 Base = ST->getBasePtr();
16474 MMO = ST->getMemOperand();
16494 SDValue Src =
N->getOperand(SrcOpnd);
16495 MVT VecTy = Src.getValueType().getSimpleVT();
16498 if (VecTy != MVT::v2f64) {
16499 Src = DAG.
getNode(ISD::BITCAST, dl, MVT::v2f64, Src);
16504 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16510 StoreOps, VecTy, MMO);
16517 DAGCombinerInfo &DCI)
const {
16520 unsigned Opcode =
N->getOperand(1).getOpcode();
16522 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16526 &&
"Not a FP_TO_INT Instruction!");
16528 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16529 EVT Op1VT =
N->getOperand(1).getValueType();
16532 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16536 bool ValidTypeForStoreFltAsInt =
16537 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16538 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16541 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16544 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16552 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16567 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16568 for (
int i = 1, e = Mask.size(); i < e; i++) {
16569 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16571 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16573 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16584 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16585 FirstOp =
Op.getOperand(i);
16591 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16592 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16600 if (
Op.getOpcode() != ISD::BITCAST)
16602 Op =
Op.getOperand(0);
16618 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16619 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16621 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16623 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16624 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16625 int Idx = ShuffV[
I];
16626 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16627 ShuffV[
I] += LHSEltFixup;
16628 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16629 ShuffV[
I] += RHSEltFixup;
16640 SDLoc dl(OrigSToV);
16643 "Expecting a SCALAR_TO_VECTOR here");
16656 "Cannot produce a permuted scalar_to_vector for one element vector");
16658 unsigned ResultInElt = NumElts / 2;
16664 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
16669 int HalfVec,
int LHSLastElementDefined,
16670 int RHSLastElementDefined) {
16671 for (
int Index : ShuffV) {
16675 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16676 (Index > LHSLastElementDefined))
16679 if ((RHSLastElementDefined >= 0) &&
16680 (Index > HalfVec + RHSLastElementDefined))
16687 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16688 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16704 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16705 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16708 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16709 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16710 return SToVPermuted;
16730 int NumElts =
LHS.getValueType().getVectorNumElements();
16733 bool IsLittleEndian = Subtarget.isLittleEndian();
16740 if (!Subtarget.hasDirectMove())
16756 SmallVector<int, 16> ShuffV(Mask);
16759 if (SToVLHS || SToVRHS) {
16762 int ShuffleNumElts = ShuffV.
size();
16763 int HalfVec = ShuffleNumElts / 2;
16769 unsigned LHSNumValidElts = HalfVec;
16770 unsigned RHSNumValidElts = HalfVec;
16775 int LHSFirstElt = 0;
16776 int RHSFirstElt = ShuffleNumElts;
16777 int LHSLastElt = -1;
16778 int RHSLastElt = -1;
16786 int LHSScalarSize = 0;
16787 int RHSScalarSize = 0;
16790 if (!IsLittleEndian && LHSScalarSize >= 64)
16795 if (!IsLittleEndian && RHSScalarSize >= 64)
16798 if (LHSScalarSize != 0)
16800 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
16801 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
16802 if (RHSScalarSize != 0)
16804 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
16805 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
16816 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
16817 LHSNumValidElts, RHSNumValidElts, Subtarget);
16843 if (IsLittleEndian) {
16846 if (Mask[0] < NumElts)
16847 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16851 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16856 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
16860 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
16865 if (Mask[0] < NumElts)
16866 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
16870 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
16875 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16879 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
16889 if (IsLittleEndian)
16898 DAGCombinerInfo &DCI)
const {
16900 "Not a reverse memop pattern!");
16902 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
16905 auto I =
Mask.rbegin();
16906 auto E =
Mask.rend();
16908 for (;
I !=
E; ++
I) {
16916 SelectionDAG &DAG = DCI.DAG;
16919 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
16925 if (!Subtarget.hasP9Vector())
16928 if(!IsElementReverse(SVN))
16931 if (LSBase->
getOpcode() == ISD::LOAD) {
16935 for (SDUse &Use : LSBase->
uses())
16936 if (
Use.getResNo() == 0 &&
16943 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
16947 if (LSBase->
getOpcode() == ISD::STORE) {
16958 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
16967 if (IntrinsicID == Intrinsic::ppc_stdcx)
16969 else if (IntrinsicID == Intrinsic::ppc_stwcx)
16971 else if (IntrinsicID == Intrinsic::ppc_sthcx)
16973 else if (IntrinsicID == Intrinsic::ppc_stbcx)
16982 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
16986 if (
LHS->getOpcode() == PPCISD::ADDE &&
16999 switch (
N->getOpcode()) {
17002 return combineADD(
N, DCI);
17028 return combineSHL(
N, DCI);
17030 return combineSRA(
N, DCI);
17032 return combineSRL(
N, DCI);
17034 return combineMUL(
N, DCI);
17036 case PPCISD::FNMSUB:
17037 return combineFMALike(
N, DCI);
17040 return N->getOperand(0);
17044 return N->getOperand(0);
17050 return N->getOperand(0);
17056 return DAGCombineExtBoolTrunc(
N, DCI);
17058 return combineTRUNCATE(
N, DCI);
17060 if (
SDValue CSCC = combineSetCC(
N, DCI))
17064 return DAGCombineTruncBoolExt(
N, DCI);
17067 return combineFPToIntToFP(
N, DCI);
17076 EVT Op1VT =
N->getOperand(1).getValueType();
17077 unsigned Opcode =
N->getOperand(1).getOpcode();
17081 SDValue Val = combineStoreFPToInt(
N, DCI);
17095 N->getOperand(1).getNode()->hasOneUse() &&
17096 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17097 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17105 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17112 if (Op1VT.
bitsGT(mVT)) {
17117 if (Op1VT == MVT::i64)
17122 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17142 ST->getBasePtr(), ST->getOffset(), MemVT,
17143 ST->getMemOperand(), ST->getAddressingMode(),
17147 return ST->isUnindexed()
17156 if (Subtarget.needsSwapsForVSXMemOps() &&
17157 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17158 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17165 EVT VT = LD->getValueType(0);
17171 if (Subtarget.needsSwapsForVSXMemOps() &&
17172 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17173 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17184 auto ReplaceTwoFloatLoad = [&]() {
17185 if (VT != MVT::i64)
17200 if (!LD->hasNUsesOfValue(2, 0))
17203 auto UI = LD->user_begin();
17204 while (UI.getUse().getResNo() != 0) ++UI;
17206 while (UI.getUse().getResNo() != 0) ++UI;
17207 SDNode *RightShift = *UI;
17215 if (RightShift->getOpcode() !=
ISD::SRL ||
17217 RightShift->getConstantOperandVal(1) != 32 ||
17218 !RightShift->hasOneUse())
17221 SDNode *Trunc2 = *RightShift->user_begin();
17230 if (Bitcast->getOpcode() != ISD::BITCAST ||
17231 Bitcast->getValueType(0) != MVT::f32)
17233 if (Bitcast2->
getOpcode() != ISD::BITCAST ||
17237 if (Subtarget.isLittleEndian())
17243 SDValue BasePtr = LD->getBasePtr();
17244 if (LD->isIndexed()) {
17246 "Non-pre-inc AM on PPC?");
17254 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17255 LD->getPointerInfo(), LD->getAlign(),
17256 MMOFlags, LD->getAAInfo());
17262 LD->getPointerInfo().getWithOffset(4),
17265 if (LD->isIndexed()) {
17279 if (ReplaceTwoFloatLoad())
17282 EVT MemVT = LD->getMemoryVT();
17285 if (LD->isUnindexed() && VT.
isVector() &&
17288 !Subtarget.hasP8Vector() &&
17289 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17290 VT == MVT::v4f32))) &&
17291 LD->getAlign() < ABIAlignment) {
17293 SDValue Chain = LD->getChain();
17294 SDValue Ptr = LD->getBasePtr();
17295 bool isLittleEndian = Subtarget.isLittleEndian();
17322 MVT PermCntlTy, PermTy, LDTy;
17323 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17324 : Intrinsic::ppc_altivec_lvsl;
17325 IntrLD = Intrinsic::ppc_altivec_lvx;
17326 IntrPerm = Intrinsic::ppc_altivec_vperm;
17327 PermCntlTy = MVT::v16i8;
17328 PermTy = MVT::v4i32;
17347 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
17351 BaseLoadOps, LDTy, BaseMMO);
17360 int IncValue = IncOffset;
17377 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
17381 ExtraLoadOps, LDTy, ExtraMMO);
17392 if (isLittleEndian)
17394 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17397 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17400 Perm = Subtarget.hasAltivec()
17401 ? DAG.
getNode(ISD::BITCAST, dl, VT, Perm)
17415 bool isLittleEndian = Subtarget.isLittleEndian();
17416 unsigned IID =
N->getConstantOperandVal(0);
17417 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17418 : Intrinsic::ppc_altivec_lvsl);
17419 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17426 .zext(
Add.getScalarValueSizeInBits()))) {
17427 SDNode *BasePtr =
Add->getOperand(0).getNode();
17428 for (
SDNode *U : BasePtr->users()) {
17430 U->getConstantOperandVal(0) == IID) {
17441 SDNode *BasePtr =
Add->getOperand(0).getNode();
17442 for (
SDNode *U : BasePtr->users()) {
17445 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17451 V->getConstantOperandVal(0) == IID) {
17463 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17464 IID == Intrinsic::ppc_altivec_vmaxsh ||
17465 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17496 switch (
N->getConstantOperandVal(1)) {
17499 case Intrinsic::ppc_altivec_vsum4sbs:
17500 case Intrinsic::ppc_altivec_vsum4shs:
17501 case Intrinsic::ppc_altivec_vsum4ubs: {
17508 APInt APSplatBits, APSplatUndef;
17509 unsigned SplatBitSize;
17512 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17513 !Subtarget.isLittleEndian());
17515 if (BVNIsConstantSplat && APSplatBits == 0)
17520 case Intrinsic::ppc_vsx_lxvw4x:
17521 case Intrinsic::ppc_vsx_lxvd2x:
17524 if (Subtarget.needsSwapsForVSXMemOps())
17532 if (Subtarget.needsSwapsForVSXMemOps()) {
17533 switch (
N->getConstantOperandVal(1)) {
17536 case Intrinsic::ppc_vsx_stxvw4x:
17537 case Intrinsic::ppc_vsx_stxvd2x:
17546 bool Is64BitBswapOn64BitTgt =
17547 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17549 N->getOperand(0).hasOneUse();
17550 if (IsSingleUseNormalLd &&
17551 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17552 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17563 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17564 MVT::i64 : MVT::i32, MVT::Other),
17565 Ops, LD->getMemoryVT(), LD->getMemOperand());
17569 if (
N->getValueType(0) == MVT::i16)
17586 !IsSingleUseNormalLd)
17591 if (!LD->isSimple())
17593 SDValue BasePtr = LD->getBasePtr();
17595 LD->getPointerInfo(), LD->getAlign());
17600 LD->getMemOperand(), 4, 4);
17604 if (Subtarget.isLittleEndian())
17610 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
17619 if (!
N->getOperand(0).hasOneUse() &&
17620 !
N->getOperand(1).hasOneUse() &&
17621 !
N->getOperand(2).hasOneUse()) {
17624 SDNode *VCMPrecNode =
nullptr;
17626 SDNode *LHSN =
N->getOperand(0).getNode();
17628 if (
User->getOpcode() == PPCISD::VCMP_rec &&
17632 VCMPrecNode =
User;
17644 SDNode *FlagUser =
nullptr;
17646 FlagUser ==
nullptr; ++UI) {
17647 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
17660 return SDValue(VCMPrecNode, 0);
17671 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
17682 auto RHSAPInt = RHS->getAsAPIntVal();
17683 if (!RHSAPInt.isIntN(64))
17686 unsigned Val = RHSAPInt.getZExtValue();
17687 auto isImpossibleCompare = [&]() {
17690 if (Val != 0 && Val != 1) {
17692 return N->getOperand(0);
17694 return DAG.
getNode(ISD::BR, dl, MVT::Other,
17695 N->getOperand(0),
N->getOperand(4));
17700 unsigned StoreWidth = 0;
17703 if (
SDValue Impossible = isImpossibleCompare())
17715 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
17719 PPCISD::STORE_COND, dl,
17721 MemNode->getMemoryVT(), MemNode->getMemOperand());
17725 if (
N->getOperand(0) == LHS.getValue(1))
17736 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
17738 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
17744 assert(isDot &&
"Can't compare against a vector result!");
17746 if (
SDValue Impossible = isImpossibleCompare())
17749 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
17756 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
17761 switch (LHS.getConstantOperandVal(1)) {
17777 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
17780 N->getOperand(4), CompNode.
getValue(1));
17785 return DAGCombineBuildVector(
N, DCI);
17798 EVT VT =
N->getValueType(0);
17799 if (VT == MVT::i64 && !Subtarget.isPPC64())
17801 if ((VT != MVT::i32 && VT != MVT::i64) ||
17809 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
17829 const APInt &DemandedElts,
17831 unsigned Depth)
const {
17833 switch (
Op.getOpcode()) {
17835 case PPCISD::LBRX: {
17838 Known.
Zero = 0xFFFF0000;
17841 case PPCISD::ADDE: {
17842 if (
Op.getResNo() == 0) {
17847 Known.
Zero = ~1ULL;
17852 switch (
Op.getConstantOperandVal(0)) {
17854 case Intrinsic::ppc_altivec_vcmpbfp_p:
17855 case Intrinsic::ppc_altivec_vcmpeqfp_p:
17856 case Intrinsic::ppc_altivec_vcmpequb_p:
17857 case Intrinsic::ppc_altivec_vcmpequh_p:
17858 case Intrinsic::ppc_altivec_vcmpequw_p:
17859 case Intrinsic::ppc_altivec_vcmpequd_p:
17860 case Intrinsic::ppc_altivec_vcmpequq_p:
17861 case Intrinsic::ppc_altivec_vcmpgefp_p:
17862 case Intrinsic::ppc_altivec_vcmpgtfp_p:
17863 case Intrinsic::ppc_altivec_vcmpgtsb_p:
17864 case Intrinsic::ppc_altivec_vcmpgtsh_p:
17865 case Intrinsic::ppc_altivec_vcmpgtsw_p:
17866 case Intrinsic::ppc_altivec_vcmpgtsd_p:
17867 case Intrinsic::ppc_altivec_vcmpgtsq_p:
17868 case Intrinsic::ppc_altivec_vcmpgtub_p:
17869 case Intrinsic::ppc_altivec_vcmpgtuh_p:
17870 case Intrinsic::ppc_altivec_vcmpgtuw_p:
17871 case Intrinsic::ppc_altivec_vcmpgtud_p:
17872 case Intrinsic::ppc_altivec_vcmpgtuq_p:
17879 switch (
Op.getConstantOperandVal(1)) {
17882 case Intrinsic::ppc_load2r:
17884 Known.
Zero = 0xFFFF0000;
17893 switch (Subtarget.getCPUDirective()) {
17915 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
17924 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
17926 LoopSize +=
TII->getInstSizeInBytes(J);
17931 if (LoopSize > 16 && LoopSize <= 32)
17945 if (Constraint.
size() == 1) {
17946 switch (Constraint[0]) {
17964 }
else if (Constraint ==
"wc") {
17966 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
17967 Constraint ==
"wf" || Constraint ==
"ws" ||
17968 Constraint ==
"wi" || Constraint ==
"ww") {
17981 Value *CallOperandVal =
info.CallOperandVal;
17984 if (!CallOperandVal)
17991 else if ((
StringRef(constraint) ==
"wa" ||
18003 switch (*constraint) {
18033std::pair<unsigned, const TargetRegisterClass *>
18037 if (Constraint.
size() == 1) {
18039 switch (Constraint[0]) {
18041 if (VT == MVT::i64 && Subtarget.isPPC64())
18042 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18043 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18045 if (VT == MVT::i64 && Subtarget.isPPC64())
18046 return std::make_pair(0U, &PPC::G8RCRegClass);
18047 return std::make_pair(0U, &PPC::GPRCRegClass);
18053 if (Subtarget.hasSPE()) {
18054 if (VT == MVT::f32 || VT == MVT::i32)
18055 return std::make_pair(0U, &PPC::GPRCRegClass);
18056 if (VT == MVT::f64 || VT == MVT::i64)
18057 return std::make_pair(0U, &PPC::SPERCRegClass);
18059 if (VT == MVT::f32 || VT == MVT::i32)
18060 return std::make_pair(0U, &PPC::F4RCRegClass);
18061 if (VT == MVT::f64 || VT == MVT::i64)
18062 return std::make_pair(0U, &PPC::F8RCRegClass);
18066 if (Subtarget.hasAltivec() && VT.
isVector())
18067 return std::make_pair(0U, &PPC::VRRCRegClass);
18068 else if (Subtarget.hasVSX())
18070 return std::make_pair(0U, &PPC::VFRCRegClass);
18073 return std::make_pair(0U, &PPC::CRRCRegClass);
18075 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18077 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18078 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18079 Constraint ==
"wf" || Constraint ==
"wi") &&
18080 Subtarget.hasVSX()) {
18084 return std::make_pair(0U, &PPC::VSRCRegClass);
18085 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18086 return std::make_pair(0U, &PPC::VSSRCRegClass);
18087 return std::make_pair(0U, &PPC::VSFRCRegClass);
18088 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18089 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18090 return std::make_pair(0U, &PPC::VSSRCRegClass);
18092 return std::make_pair(0U, &PPC::VSFRCRegClass);
18093 }
else if (Constraint ==
"lr") {
18094 if (VT == MVT::i64)
18095 return std::make_pair(0U, &PPC::LR8RCRegClass);
18097 return std::make_pair(0U, &PPC::LRRCRegClass);
18102 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18106 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18107 int VSNum = atoi(Constraint.
data() + 3);
18108 assert(VSNum >= 0 && VSNum <= 63 &&
18109 "Attempted to access a vsr out of range");
18111 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18112 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18117 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18118 int RegNum = atoi(Constraint.
data() + 2);
18119 if (RegNum > 31 || RegNum < 0)
18121 if (VT == MVT::f32 || VT == MVT::i32)
18122 return Subtarget.hasSPE()
18123 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18124 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18125 if (VT == MVT::f64 || VT == MVT::i64)
18126 return Subtarget.hasSPE()
18127 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18128 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18132 std::pair<unsigned, const TargetRegisterClass *> R =
18141 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18142 PPC::GPRCRegClass.contains(R.first))
18143 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18144 PPC::sub_32, &PPC::G8RCRegClass),
18145 &PPC::G8RCRegClass);
18148 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18149 R.first = PPC::CR0;
18150 R.second = &PPC::CRRCRegClass;
18154 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18155 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18156 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18157 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18158 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18159 "default AIX AltiVec ABI and cannot be used\n";
18169 std::vector<SDValue> &
Ops,
18174 if (Constraint.
size() > 1)
18177 char Letter = Constraint[0];
18192 EVT TCVT = MVT::i64;
18233 if (Result.getNode()) {
18234 Ops.push_back(Result);
18245 if (
I.getNumOperands() <= 1)
18249 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18250 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18251 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18254 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18270 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18282 switch (AM.
Scale) {
18310 unsigned Depth =
Op.getConstantOperandVal(0);
18334 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18342 unsigned Depth =
Op.getConstantOperandVal(0);
18349 bool isPPC64 = PtrVT == MVT::i64;
18355 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18357 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18363 FrameAddr, MachinePointerInfo());
18367#define GET_REGISTER_MATCHER
18368#include "PPCGenAsmMatcher.inc"
18372 bool IsPPC64 = Subtarget.isPPC64();
18384 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18390 Reg = Reg.id() - PPC::R0 + PPC::X0;
18397 if (Subtarget.is32BitELFABI())
18402 if (Subtarget.isAIXABI())
18416 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18432 case Intrinsic::ppc_atomicrmw_xchg_i128:
18433 case Intrinsic::ppc_atomicrmw_add_i128:
18434 case Intrinsic::ppc_atomicrmw_sub_i128:
18435 case Intrinsic::ppc_atomicrmw_nand_i128:
18436 case Intrinsic::ppc_atomicrmw_and_i128:
18437 case Intrinsic::ppc_atomicrmw_or_i128:
18438 case Intrinsic::ppc_atomicrmw_xor_i128:
18439 case Intrinsic::ppc_cmpxchg_i128:
18441 Info.memVT = MVT::i128;
18442 Info.ptrVal =
I.getArgOperand(0);
18444 Info.align =
Align(16);
18448 case Intrinsic::ppc_atomic_load_i128:
18450 Info.memVT = MVT::i128;
18451 Info.ptrVal =
I.getArgOperand(0);
18453 Info.align =
Align(16);
18456 case Intrinsic::ppc_atomic_store_i128:
18458 Info.memVT = MVT::i128;
18459 Info.ptrVal =
I.getArgOperand(2);
18461 Info.align =
Align(16);
18464 case Intrinsic::ppc_altivec_lvx:
18465 case Intrinsic::ppc_altivec_lvxl:
18466 case Intrinsic::ppc_altivec_lvebx:
18467 case Intrinsic::ppc_altivec_lvehx:
18468 case Intrinsic::ppc_altivec_lvewx:
18469 case Intrinsic::ppc_vsx_lxvd2x:
18470 case Intrinsic::ppc_vsx_lxvw4x:
18471 case Intrinsic::ppc_vsx_lxvd2x_be:
18472 case Intrinsic::ppc_vsx_lxvw4x_be:
18473 case Intrinsic::ppc_vsx_lxvl:
18474 case Intrinsic::ppc_vsx_lxvll: {
18477 case Intrinsic::ppc_altivec_lvebx:
18480 case Intrinsic::ppc_altivec_lvehx:
18483 case Intrinsic::ppc_altivec_lvewx:
18486 case Intrinsic::ppc_vsx_lxvd2x:
18487 case Intrinsic::ppc_vsx_lxvd2x_be:
18497 Info.ptrVal =
I.getArgOperand(0);
18500 Info.align =
Align(1);
18504 case Intrinsic::ppc_altivec_stvx:
18505 case Intrinsic::ppc_altivec_stvxl:
18506 case Intrinsic::ppc_altivec_stvebx:
18507 case Intrinsic::ppc_altivec_stvehx:
18508 case Intrinsic::ppc_altivec_stvewx:
18509 case Intrinsic::ppc_vsx_stxvd2x:
18510 case Intrinsic::ppc_vsx_stxvw4x:
18511 case Intrinsic::ppc_vsx_stxvd2x_be:
18512 case Intrinsic::ppc_vsx_stxvw4x_be:
18513 case Intrinsic::ppc_vsx_stxvl:
18514 case Intrinsic::ppc_vsx_stxvll: {
18517 case Intrinsic::ppc_altivec_stvebx:
18520 case Intrinsic::ppc_altivec_stvehx:
18523 case Intrinsic::ppc_altivec_stvewx:
18526 case Intrinsic::ppc_vsx_stxvd2x:
18527 case Intrinsic::ppc_vsx_stxvd2x_be:
18537 Info.ptrVal =
I.getArgOperand(1);
18540 Info.align =
Align(1);
18544 case Intrinsic::ppc_stdcx:
18545 case Intrinsic::ppc_stwcx:
18546 case Intrinsic::ppc_sthcx:
18547 case Intrinsic::ppc_stbcx: {
18549 auto Alignment =
Align(8);
18551 case Intrinsic::ppc_stdcx:
18554 case Intrinsic::ppc_stwcx:
18556 Alignment =
Align(4);
18558 case Intrinsic::ppc_sthcx:
18560 Alignment =
Align(2);
18562 case Intrinsic::ppc_stbcx:
18564 Alignment =
Align(1);
18569 Info.ptrVal =
I.getArgOperand(0);
18571 Info.align = Alignment;
18586 const AttributeList &FuncAttributes)
const {
18590 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
18591 if (
Op.isMemset() && Subtarget.hasVSX()) {
18596 if (TailSize > 2 && TailSize <= 4) {
18601 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
18606 if (Subtarget.isPPC64()) {
18617 assert(Ty->isIntegerTy());
18619 unsigned BitSize = Ty->getPrimitiveSizeInBits();
18620 return !(BitSize == 0 || BitSize > 64);
18628 return NumBits1 == 64 && NumBits2 == 32;
18636 return NumBits1 == 64 && NumBits2 == 32;
18643 EVT MemVT = LD->getMemoryVT();
18644 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
18645 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
18661 "invalid fpext types");
18663 if (DestVT == MVT::f128)
18678 unsigned *
Fast)
const {
18692 !Subtarget.allowsUnalignedFPAccess())
18696 if (Subtarget.hasVSX()) {
18697 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
18698 VT != MVT::v4f32 && VT != MVT::v4i32)
18705 if (VT == MVT::ppcf128)
18720 if (!ConstNode->getAPIntValue().isSignedIntN(64))
18728 int64_t Imm = ConstNode->getSExtValue();
18749 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
18751 switch (Ty->getScalarType()->getTypeID()) {
18756 return Subtarget.hasP9Vector();
18764 if (!
I->hasOneUse())
18768 assert(
User &&
"A single use instruction with no uses.");
18770 switch (
I->getOpcode()) {
18771 case Instruction::FMul: {
18773 if (
User->getOpcode() != Instruction::FSub &&
18774 User->getOpcode() != Instruction::FAdd)
18781 bool AllowContract =
I->getFastMathFlags().allowContract() &&
18782 User->getFastMathFlags().allowContract();
18788 case Instruction::Load: {
18801 if (
User->getOpcode() != Instruction::Store)
18821 static const MCPhysReg ScratchRegs[] = {
18822 PPC::X12, PPC::LR8, PPC::CTR8, 0
18825 return ScratchRegs;
18829 const Constant *PersonalityFn)
const {
18830 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
18834 const Constant *PersonalityFn)
const {
18835 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
18840 EVT VT ,
unsigned DefinedValues)
const {
18841 if (VT == MVT::v2i64)
18842 return Subtarget.hasDirectMove();
18844 if (Subtarget.hasVSX())
18871 return PPCISD::FNMSUB;
18872 case PPCISD::FNMSUB:
18878 bool LegalOps,
bool OptForSize,
18880 unsigned Depth)
const {
18884 unsigned Opc =
Op.getOpcode();
18885 EVT VT =
Op.getValueType();
18889 case PPCISD::FNMSUB:
18910 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
18914 N0Cost,
Depth + 1);
18918 N1Cost,
Depth + 1);
18920 if (NegN0 && N0Cost <= N1Cost) {
18921 Cost = std::min(N0Cost, N2Cost);
18923 }
else if (NegN1) {
18924 Cost = std::min(N1Cost, N2Cost);
18944 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
18950 bool ForCodeSize)
const {
18951 if (!VT.
isSimple() || !Subtarget.hasVSX())
18961 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
18966 APSInt IntResult(16,
false);
18971 if (IsExact && IntResult <= 15 && IntResult >= -16)
18973 return Imm.isZero();
18976 return Imm.isPosZero();
18988 unsigned Opcode =
N->getOpcode();
19008 if (Mask->getZExtValue() == OpSizeInBits - 1)
19015 DAGCombinerInfo &DCI)
const {
19016 EVT VT =
N->getValueType(0);
19019 unsigned Opc =
N->getOpcode();
19021 "Unexpected opcode.");
19028 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19032 uint64_t SplatBits = 0;
19033 bool AddSplatCase =
false;
19037 AddSplatCase =
true;
19041 if (!AddSplatCase) {
19045 unsigned SplatBitSize;
19047 APInt APSplatBits, APSplatUndef;
19049 bool BVNIsConstantSplat =
19051 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19052 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19063 if (SplatBits == (EltBits - 1)) {
19067 NewOpc = PPCISD::SHL;
19070 NewOpc = PPCISD::SRL;
19073 NewOpc = PPCISD::SRA;
19077 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19085 if (EltTy != MVT::i64 || SplatBits != 1)
19088 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19091SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19095 if (
N->getValueType(0).isVector())
19096 return combineVectorShift(
N, DCI);
19100 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19103 N->getValueType(0) != MVT::i64)
19118 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19124SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19128 if (
N->getValueType(0).isVector())
19129 return combineVectorShift(
N, DCI);
19134SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19138 if (
N->getValueType(0).isVector())
19139 return combineVectorShift(
N, DCI);
19150 if (!Subtarget.isPPC64())
19156 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19158 Op.getValueType() != MVT::i64)
19162 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19163 Cmp.getOperand(0).getValueType() != MVT::i64)
19167 int64_t NegConstant = 0 -
Constant->getSExtValue();
19176 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19177 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19180 if (LHSHasPattern && !RHSHasPattern)
19182 else if (!LHSHasPattern && !RHSHasPattern)
19186 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19189 SDValue Z = Cmp.getOperand(0);
19191 int64_t NegConstant = 0 -
Constant->getSExtValue();
19204 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19222 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19252 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19255 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19263 if (!GSDN || !ConstNode)
19291 EVT VT =
N->getValueType(0);
19292 if (!Subtarget.hasVSX())
19296 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19308 unsigned NumOfEles =
RHS.getNumOperands();
19309 for (
unsigned i = 0; i < NumOfEles; ++i) {
19311 if (!CN || CN->getSExtValue() != 1)
19326SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19348 DAGCombinerInfo &DCI)
const {
19350 if (Subtarget.useCRBits()) {
19352 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19353 return CRTruncValue;
19360 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19363 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19373 EltToExtract = EltToExtract ? 0 : 1;
19383 return DCI.DAG.getNode(
19385 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19390SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19391 SelectionDAG &DAG = DCI.DAG;
19394 if (!ConstOpOrElement)
19402 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19403 switch (this->Subtarget.getCPUDirective()) {
19426 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19430 EVT VT =
N->getValueType(0);
19435 APInt MulAmtAbs = MulAmt.
abs();
19437 if ((MulAmtAbs - 1).isPowerOf2()) {
19441 if (!IsProfitable(IsNeg,
true, VT))
19454 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19458 if (!IsProfitable(IsNeg,
false, VT))
19479 DAGCombinerInfo &DCI)
const {
19483 SDNodeFlags
Flags =
N->getFlags();
19484 EVT VT =
N->getValueType(0);
19485 SelectionDAG &DAG = DCI.DAG;
19487 unsigned Opc =
N->getOpcode();
19489 bool LegalOps = !DCI.isBeforeLegalizeOps();
19497 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
19513bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19515 if (!Subtarget.is64BitELFABI())
19525 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19530 if (!Callee ||
Callee->isVarArg())
19543bool PPCTargetLowering::
19544isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19549 if (CI->getBitWidth() > 64)
19551 int64_t ConstVal = CI->getZExtValue();
19553 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19562PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19568 if ((Flags & FlagSet) == FlagSet)
19571 if ((Flags & FlagSet) == FlagSet)
19574 if ((Flags & FlagSet) == FlagSet)
19577 if ((Flags & FlagSet) == FlagSet)
19598 if ((FrameIndexAlign % 4) != 0)
19599 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
19600 if ((FrameIndexAlign % 16) != 0)
19601 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
19605 if ((FrameIndexAlign % 4) == 0)
19607 if ((FrameIndexAlign % 16) == 0)
19620 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
19621 if ((Imm & 0x3) == 0)
19623 if ((Imm & 0xf) == 0)
19629 const APInt &ConstImm = CN->getAPIntValue();
19648 const APInt &ConstImm = CN->getAPIntValue();
19658 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
19669 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
19678unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
19683 if (!Subtarget.hasP9Vector())
19688 if (Subtarget.hasPrefixInstrs())
19691 if (Subtarget.hasSPE())
19700 unsigned ParentOp = Parent->
getOpcode();
19704 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
19705 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
19717 if (LSB->isIndexed())
19723 assert(MN &&
"Parent should be a MemSDNode!");
19728 "Not expecting scalar integers larger than 16 bytes!");
19731 else if (
Size == 32)
19738 else if (
Size == 256) {
19739 assert(Subtarget.pairedVectorMemops() &&
19740 "256-bit vectors are only available when paired vector memops is "
19748 else if (MemVT == MVT::f128 || MemVT.
isVector())
19779 FlagSet &= ~PPC::MOF_NoExt;
19784 bool IsNonP1034BitConst =
19788 IsNonP1034BitConst)
19801 int16_t ForceXFormImm = 0;
19804 Disp =
N.getOperand(0);
19805 Base =
N.getOperand(1);
19816 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
19817 Disp =
N.getOperand(0);
19818 Base =
N.getOperand(1);
19823 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
19832 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
19838 if (PartVT == MVT::f64 &&
19839 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
19841 Val = DAG.
getNode(ISD::BITCAST,
DL, MVT::f64, Val);
19848SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
19852 EVT RetVT =
Op.getValueType();
19859 EVT ArgVT =
N.getValueType();
19863 Entry.IsZExt = !Entry.IsSExt;
19864 Args.push_back(Entry);
19872 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
19885SDValue PPCTargetLowering::lowerLibCallBasedOnType(
19886 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
19888 if (
Op.getValueType() == MVT::f32)
19889 return lowerToLibCall(LibCallFloatName,
Op, DAG);
19891 if (
Op.getValueType() == MVT::f64)
19892 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
19897bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
19898 SDNodeFlags
Flags =
Op.getNode()->getFlags();
19899 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
19903bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
19904 return Op.getNode()->getFlags().hasApproximateFuncs();
19907bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
19911SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
19912 const char *LibCallFloatName,
19913 const char *LibCallDoubleNameFinite,
19914 const char *LibCallFloatNameFinite,
19917 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
19920 if (!isLowringToMASSFiniteSafe(
Op))
19921 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
19924 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
19925 LibCallDoubleNameFinite,
Op, DAG);
19929 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
19930 "__xl_powf_finite",
Op, DAG);
19934 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
19935 "__xl_sinf_finite",
Op, DAG);
19939 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
19940 "__xl_cosf_finite",
Op, DAG);
19944 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
19945 "__xl_logf_finite",
Op, DAG);
19949 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
19950 "__xl_log10f_finite",
Op, DAG);
19954 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
19955 "__xl_expf_finite",
Op, DAG);
19980 unsigned Flags = computeMOFlags(Parent,
N, DAG);
19991 assert(Subtarget.isUsingPCRelativeCalls() &&
19992 "Must be using PC-Relative calls when a valid PC-Relative node is "
20022 Disp =
N.getOperand(1).getOperand(0);
20027 Base =
N.getOperand(0);
20035 EVT CNType = CN->getValueType(0);
20036 uint64_t CNImm = CN->getZExtValue();
20047 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20049 int32_t Addr = (int32_t)CNImm;
20054 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20070 unsigned Opcode =
N.getOpcode();
20078 Base =
N.getOperand(0);
20097 Base = FI ?
N :
N.getOperand(1);
20098 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20109 bool IsVarArg)
const {
20119 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20155 return Intrinsic::ppc_atomicrmw_xchg_i128;
20157 return Intrinsic::ppc_atomicrmw_add_i128;
20159 return Intrinsic::ppc_atomicrmw_sub_i128;
20161 return Intrinsic::ppc_atomicrmw_and_i128;
20163 return Intrinsic::ppc_atomicrmw_or_i128;
20165 return Intrinsic::ppc_atomicrmw_xor_i128;
20167 return Intrinsic::ppc_atomicrmw_nand_i128;
20175 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20177 assert(ValTy->getPrimitiveSizeInBits() == 128);
20179 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20181 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20182 Value *LoHi = Builder.CreateIntrinsic(
20184 {AlignedAddr, IncrLo, IncrHi});
20185 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20186 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20187 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20188 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20189 return Builder.CreateOr(
20190 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20197 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20199 assert(ValTy->getPrimitiveSizeInBits() == 128);
20203 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20205 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20206 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20208 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20211 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20213 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20214 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20215 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20216 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20217 return Builder.CreateOr(
20218 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20222 return Subtarget.useCRBits();
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS)
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left, SelectionDAG &DAG)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble()
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
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 checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static BranchProbability getOne()
static BranchProbability getZero()
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.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
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.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
LLVM_ABI StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
LLVM_ABI bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
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...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
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.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
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.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & 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 & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
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.
static MachineOperand CreateImm(int64_t Val)
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,...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
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.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
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...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
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 expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
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...
bool isJumpTableRelative() const override
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 LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
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.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
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
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
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.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
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)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
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 getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
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,...
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 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)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
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
static constexpr unsigned MaxRecursionDepth
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)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
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 getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
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 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 ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
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 getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
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.
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.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
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 SDValue getCondCode(ISD::CondCode Cond)
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 getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
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...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
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...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
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...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
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.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
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 setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
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
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
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...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
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.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
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).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
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.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
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.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual TargetLoweringObjectFile * getObjFileLowering() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
bool getFunctionSections() const
Return true if functions should be emitted into their own section, corresponding to -ffunction-sectio...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
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
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(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 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ ADD
Simple integer binary arithmetic operators.
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ 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...
@ SSUBO
Same for subtraction.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ 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_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ 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) ...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ 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.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
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.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
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 isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
@ Define
Register definition.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
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)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ 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.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
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 bitsGT(EVT VT) const
Return true if this has more bits than 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.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
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.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
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.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
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.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.