69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
108 "disable-p10-store-forward",
132 cl::desc(
"disable vector permute decomposition"),
136 "disable-auto-paired-vec-st",
137 cl::desc(
"disable automatically generated 32byte paired vector stores"),
142 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
146 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
151 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
155 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
156 "function to use initial-exec"));
161 "Number of shuffles lowered to a VPERM or XXPERM");
162STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
169 unsigned OpIdx,
bool IsByte,
187 initializeAddrModeMap();
190 bool isPPC64 = Subtarget.isPPC64();
192 const MVT RegVT = Subtarget.getScalarIntVT();
200 if (!Subtarget.hasEFPU2())
217 if (!Subtarget.hasP10Vector()) {
246 if (Subtarget.isISA3_0()) {
279 if (!Subtarget.hasSPE()) {
286 if (Subtarget.useCRBits()) {
289 if (isPPC64 || Subtarget.hasFPCVT()) {
355 if (Subtarget.isISA3_0()) {
390 if (!Subtarget.hasSPE()) {
395 if (Subtarget.hasVSX()) {
400 if (Subtarget.hasFSQRT()) {
405 if (Subtarget.hasFPRND()) {
446 if (Subtarget.hasSPE()) {
456 if (Subtarget.hasSPE())
460 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
463 if (!Subtarget.hasFSQRT() &&
464 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
467 if (Subtarget.hasFCPSGN()) {
475 if (Subtarget.hasFPRND()) {
489 if (Subtarget.isISA3_1()) {
495 ((Subtarget.hasP8Vector()) && isPPC64) ?
Custom
500 if (Subtarget.isISA3_0()) {
520 if (!Subtarget.useCRBits()) {
533 if (!Subtarget.useCRBits())
536 if (Subtarget.hasFPU()) {
547 if (!Subtarget.useCRBits())
552 if (Subtarget.hasSPE()) {
584 if (Subtarget.hasDirectMove() && isPPC64) {
648 if (Subtarget.is64BitELFABI()) {
659 }
else if (Subtarget.is32BitELFABI()) {
667 if (Subtarget.is32BitELFABI())
683 if (Subtarget.isISA3_0() && isPPC64) {
711 if (Subtarget.hasSPE()) {
733 if (Subtarget.has64BitSupport()) {
748 if (Subtarget.hasLFIWAX() || isPPC64) {
754 if (Subtarget.hasSPE()) {
764 if (Subtarget.hasFPCVT()) {
765 if (Subtarget.has64BitSupport()) {
786 if (Subtarget.use64BitRegs()) {
804 if (Subtarget.has64BitSupport()) {
811 if (Subtarget.hasVSX()) {
824 if (Subtarget.hasAltivec()) {
825 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
842 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
855 if (Subtarget.hasVSX()) {
864 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
874 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
948 if (!Subtarget.hasP8Vector()) {
990 if (Subtarget.hasAltivec())
991 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
994 if (Subtarget.hasP8Altivec())
1005 if (Subtarget.hasVSX()) {
1011 if (Subtarget.hasP8Altivec())
1016 if (Subtarget.isISA3_1()) {
1062 if (Subtarget.hasVSX()) {
1065 if (Subtarget.hasP8Vector()) {
1069 if (Subtarget.hasDirectMove() && isPPC64) {
1118 if (Subtarget.hasP8Vector())
1127 if (Subtarget.hasP8Altivec()) {
1154 if (Subtarget.isISA3_1())
1257 if (Subtarget.hasP8Altivec()) {
1262 if (Subtarget.hasP9Vector()) {
1267 if (Subtarget.useCRBits()) {
1327 }
else if (Subtarget.hasVSX()) {
1352 for (
MVT VT : {MVT::f32, MVT::f64}) {
1371 if (Subtarget.hasP9Altivec()) {
1372 if (Subtarget.isISA3_1()) {
1395 if (Subtarget.hasP10Vector()) {
1410 if (Subtarget.pairedVectorMemops()) {
1415 if (Subtarget.hasMMA()) {
1416 if (Subtarget.isISAFuture()) {
1432 if (Subtarget.has64BitSupport())
1435 if (Subtarget.isISA3_1())
1453 if (Subtarget.hasAltivec()) {
1471 if (Subtarget.hasFPCVT())
1474 if (Subtarget.useCRBits())
1483 if (Subtarget.useCRBits()) {
1487 if (Subtarget.hasP8Vector())
1492 if (Subtarget.useCRBits()) {
1508 auto CPUDirective = Subtarget.getCPUDirective();
1509 switch (CPUDirective) {
1532 if (Subtarget.enableMachineScheduler())
1606void PPCTargetLowering::initializeAddrModeMap() {
1657 if (MaxAlign == MaxMaxAlign)
1660 if (MaxMaxAlign >= 32 &&
1661 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1662 MaxAlign =
Align(32);
1663 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1665 MaxAlign =
Align(16);
1669 if (EltAlign > MaxAlign)
1670 MaxAlign = EltAlign;
1672 for (
auto *EltTy : STy->elements()) {
1675 if (EltAlign > MaxAlign)
1676 MaxAlign = EltAlign;
1677 if (MaxAlign == MaxMaxAlign)
1690 if (Subtarget.hasAltivec())
1696 return Subtarget.useSoftFloat();
1700 return Subtarget.hasSPE();
1708 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1709 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1713 if (VTy->getScalarType()->isIntegerTy()) {
1715 if (ElemSizeInBits == 32) {
1716 Index = Subtarget.isLittleEndian() ? 2 : 1;
1719 if (ElemSizeInBits == 64) {
1720 Index = Subtarget.isLittleEndian() ? 1 : 0;
1731 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1748 return CFP->getValueAPF().isZero();
1753 return CFP->getValueAPF().isZero();
1761 return Op < 0 ||
Op == Val;
1773 if (ShuffleKind == 0) {
1776 for (
unsigned i = 0; i != 16; ++i)
1779 }
else if (ShuffleKind == 2) {
1782 for (
unsigned i = 0; i != 16; ++i)
1785 }
else if (ShuffleKind == 1) {
1786 unsigned j = IsLE ? 0 : 1;
1787 for (
unsigned i = 0; i != 8; ++i)
1804 if (ShuffleKind == 0) {
1807 for (
unsigned i = 0; i != 16; i += 2)
1811 }
else if (ShuffleKind == 2) {
1814 for (
unsigned i = 0; i != 16; i += 2)
1818 }
else if (ShuffleKind == 1) {
1819 unsigned j = IsLE ? 0 : 2;
1820 for (
unsigned i = 0; i != 8; i += 2)
1841 if (!Subtarget.hasP8Vector())
1845 if (ShuffleKind == 0) {
1848 for (
unsigned i = 0; i != 16; i += 4)
1854 }
else if (ShuffleKind == 2) {
1857 for (
unsigned i = 0; i != 16; i += 4)
1863 }
else if (ShuffleKind == 1) {
1864 unsigned j = IsLE ? 0 : 4;
1865 for (
unsigned i = 0; i != 8; i += 4)
1882 unsigned LHSStart,
unsigned RHSStart) {
1883 if (
N->getValueType(0) != MVT::v16i8)
1885 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1886 "Unsupported merge size!");
1888 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1889 for (
unsigned j = 0; j != UnitSize; ++j) {
1891 LHSStart+j+i*UnitSize) ||
1893 RHSStart+j+i*UnitSize))
1908 if (ShuffleKind == 1)
1910 else if (ShuffleKind == 2)
1915 if (ShuffleKind == 1)
1917 else if (ShuffleKind == 0)
1933 if (ShuffleKind == 1)
1935 else if (ShuffleKind == 2)
1940 if (ShuffleKind == 1)
1942 else if (ShuffleKind == 0)
1992 unsigned RHSStartValue) {
1993 if (
N->getValueType(0) != MVT::v16i8)
1996 for (
unsigned i = 0; i < 2; ++i)
1997 for (
unsigned j = 0; j < 4; ++j)
1999 i*RHSStartValue+j+IndexOffset) ||
2001 i*RHSStartValue+j+IndexOffset+8))
2023 unsigned indexOffset = CheckEven ? 4 : 0;
2024 if (ShuffleKind == 1)
2026 else if (ShuffleKind == 2)
2032 unsigned indexOffset = CheckEven ? 0 : 4;
2033 if (ShuffleKind == 1)
2035 else if (ShuffleKind == 0)
2051 if (
N->getValueType(0) != MVT::v16i8)
2058 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2061 if (i == 16)
return -1;
2066 if (ShiftAmt < i)
return -1;
2071 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2073 for (++i; i != 16; ++i)
2076 }
else if (ShuffleKind == 1) {
2078 for (++i; i != 16; ++i)
2085 ShiftAmt = 16 - ShiftAmt;
2094 EVT VT =
N->getValueType(0);
2095 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2096 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2099 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2103 if (
N->getMaskElt(0) % EltSize != 0)
2108 unsigned ElementBase =
N->getMaskElt(0);
2111 if (ElementBase >= 16)
2116 for (
unsigned i = 1; i != EltSize; ++i)
2117 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2120 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2122 if (
N->getMaskElt(i) < 0) {
2123 for (
unsigned j = 1; j != EltSize; ++j)
2124 if (
N->getMaskElt(i + j) >= 0)
2127 for (
unsigned j = 0; j != EltSize; ++j)
2128 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2145 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2146 "Unexpected element width.");
2147 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2149 unsigned NumOfElem = 16 / Width;
2150 unsigned MaskVal[16];
2151 for (
unsigned i = 0; i < NumOfElem; ++i) {
2152 MaskVal[0] =
N->getMaskElt(i * Width);
2153 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2155 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2159 for (
unsigned int j = 1; j < Width; ++j) {
2160 MaskVal[j] =
N->getMaskElt(i * Width + j);
2161 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2171 unsigned &InsertAtByte,
bool &
Swap,
bool IsLE) {
2176 unsigned M0 =
N->getMaskElt(0) / 4;
2177 unsigned M1 =
N->getMaskElt(4) / 4;
2178 unsigned M2 =
N->getMaskElt(8) / 4;
2179 unsigned M3 =
N->getMaskElt(12) / 4;
2180 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2181 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2186 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2187 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2188 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2189 InsertAtByte = IsLE ? 12 : 0;
2194 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2195 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2196 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2197 InsertAtByte = IsLE ? 8 : 4;
2202 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2203 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2204 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2205 InsertAtByte = IsLE ? 4 : 8;
2210 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2211 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2212 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2213 InsertAtByte = IsLE ? 0 : 12;
2220 if (
N->getOperand(1).isUndef()) {
2223 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2224 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2225 InsertAtByte = IsLE ? 12 : 0;
2228 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2229 InsertAtByte = IsLE ? 8 : 4;
2232 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2233 InsertAtByte = IsLE ? 4 : 8;
2236 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2237 InsertAtByte = IsLE ? 0 : 12;
2246 bool &
Swap,
bool IsLE) {
2247 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2253 unsigned M0 =
N->getMaskElt(0) / 4;
2254 unsigned M1 =
N->getMaskElt(4) / 4;
2255 unsigned M2 =
N->getMaskElt(8) / 4;
2256 unsigned M3 =
N->getMaskElt(12) / 4;
2260 if (
N->getOperand(1).isUndef()) {
2261 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2262 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2265 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2271 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2275 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2280 ShiftElts = (8 -
M0) % 8;
2281 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2286 ShiftElts = (4 -
M0) % 4;
2291 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2296 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2308 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2313 for (
int i = 0; i < 16; i += Width)
2314 if (
N->getMaskElt(i) != i + Width - 1)
2345 bool &
Swap,
bool IsLE) {
2346 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2352 unsigned M0 =
N->getMaskElt(0) / 8;
2353 unsigned M1 =
N->getMaskElt(8) / 8;
2354 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2358 if (
N->getOperand(1).isUndef()) {
2359 if ((
M0 |
M1) < 2) {
2360 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2368 if (
M0 > 1 &&
M1 < 2) {
2378 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2383 }
else if (
M0 > 1 &&
M1 < 2) {
2391 DM = (
M0 << 1) + (
M1 & 1);
2406 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2411 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2427 unsigned EltSize = 16/
N->getNumOperands();
2428 if (EltSize < ByteSize) {
2429 unsigned Multiple = ByteSize/EltSize;
2431 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2434 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2435 if (
N->getOperand(i).isUndef())
continue;
2439 if (!UniquedVals[i&(Multiple-1)].
getNode())
2440 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2441 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2451 bool LeadingZero =
true;
2452 bool LeadingOnes =
true;
2453 for (
unsigned i = 0; i != Multiple-1; ++i) {
2454 if (!UniquedVals[i].
getNode())
continue;
2461 if (!UniquedVals[Multiple-1].
getNode())
2468 if (!UniquedVals[Multiple-1].
getNode())
2479 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2480 if (
N->getOperand(i).isUndef())
continue;
2482 OpVal =
N->getOperand(i);
2483 else if (OpVal !=
N->getOperand(i))
2489 unsigned ValSizeInBytes = EltSize;
2492 Value = CN->getZExtValue();
2494 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2501 if (ValSizeInBytes < ByteSize)
return SDValue();
2512 if (MaskVal == 0)
return SDValue();
2532 Imm = (int16_t)
N->getAsZExtVal();
2533 if (
N->getValueType(0) == MVT::i32)
2534 return Imm == (int32_t)
N->getAsZExtVal();
2536 return Imm == (int64_t)
N->getAsZExtVal();
2554 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2562 for (
SDNode *U :
N->users()) {
2564 if (Memop->getMemoryVT() == MVT::f64) {
2565 Base =
N.getOperand(0);
2566 Index =
N.getOperand(1);
2609 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2611 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2614 Base =
N.getOperand(0);
2615 Index =
N.getOperand(1);
2617 }
else if (
N.getOpcode() ==
ISD::OR) {
2619 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2631 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2632 Base =
N.getOperand(0);
2633 Index =
N.getOperand(1);
2703 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2709 Base =
N.getOperand(0);
2712 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2714 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2715 "Cannot handle constant offsets yet!");
2716 Disp =
N.getOperand(1).getOperand(0);
2721 Base =
N.getOperand(0);
2724 }
else if (
N.getOpcode() ==
ISD::OR) {
2727 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2741 Base =
N.getOperand(0);
2754 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm))) {
2757 CN->getValueType(0));
2762 if ((CN->getValueType(0) == MVT::i32 ||
2763 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2764 (!EncodingAlignment ||
2765 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2766 int Addr = (int)CN->getZExtValue();
2773 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2794 if (
N.getValueType() != MVT::i64)
2807 Base =
N.getOperand(0);
2823 Base =
N.getOperand(0);
2856 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2857 Base =
N.getOperand(0);
2858 Index =
N.getOperand(1);
2880 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2901 EVT MemVT = LD->getMemoryVT();
2908 if (!ST.hasP8Vector())
2913 if (!ST.hasP9Vector())
2925 if (
Use.getResNo() == 0 &&
2927 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2947 Ptr = LD->getBasePtr();
2948 VT = LD->getMemoryVT();
2949 Alignment = LD->getAlign();
2951 Ptr = ST->getBasePtr();
2952 VT = ST->getMemoryVT();
2953 Alignment = ST->getAlign();
2992 if (VT != MVT::i64) {
2997 if (Alignment <
Align(4))
3007 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3024 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3066 EVT VT = Subtarget.getScalarIntVT();
3068 : Subtarget.isAIXABI()
3073 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3080 EVT PtrVT =
Op.getValueType();
3086 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3087 if (Subtarget.isUsingPCRelativeCalls()) {
3092 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3096 return getTOCEntry(DAG, SDLoc(CP), GA);
3099 unsigned MOHiFlag, MOLoFlag;
3103 if (IsPIC && Subtarget.isSVR4ABI()) {
3106 return getTOCEntry(DAG, SDLoc(CP), GA);
3129 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3136 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3153 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3166 EVT PtrVT =
Op.getValueType();
3184 return getTOCEntry(DAG,
SDLoc(JT), GA);
3187 unsigned MOHiFlag, MOLoFlag;
3191 if (IsPIC && Subtarget.isSVR4ABI()) {
3194 return getTOCEntry(DAG, SDLoc(GA), GA);
3204 EVT PtrVT =
Op.getValueType();
3209 if (Subtarget.isUsingPCRelativeCalls()) {
3220 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3223 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3232 unsigned MOHiFlag, MOLoFlag;
3242 if (Subtarget.isAIXABI())
3243 return LowerGlobalTLSAddressAIX(
Op, DAG);
3245 return LowerGlobalTLSAddressLinux(
Op, DAG);
3267 if (
I.getOpcode() == Instruction::Call)
3269 if (
Function *CF = CI->getCalledFunction())
3270 if (CF->isDeclaration() &&
3271 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3279 unsigned TLSGVCnt = TLSGV.
size();
3289 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3302 const GlobalValue *GV = GA->
getGlobal();
3304 bool Is64Bit = Subtarget.isPPC64();
3308 if (Subtarget.hasAIXShLibTLSModelOpt())
3318 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3319 bool HasAIXSmallTLSGlobalAttr =
false;
3322 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3326 if (GVar->hasAttribute(
"aix-small-tls"))
3327 HasAIXSmallTLSGlobalAttr =
true;
3346 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3347 IsTLSLocalExecModel) {
3352 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3362 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3367 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3369 "currently only supported on AIX (64-bit mode).");
3371 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3375 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3379 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3381 "currently only supported on AIX (64-bit mode).");
3389 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3392 GlobalVariable *TLSGV =
3396 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3399 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3401 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3410 if (HasAIXSmallLocalDynamicTLS) {
3415 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3419 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3432 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3433 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3434 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3449 const GlobalValue *GV = GA->
getGlobal();
3451 bool is64bit = Subtarget.isPPC64();
3459 if (Subtarget.isUsingPCRelativeCalls()) {
3464 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3465 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3476 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3480 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3487 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3489 MachinePointerInfo());
3496 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3498 if (!TM.isPositionIndependent())
3499 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3505 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3511 if (Subtarget.isUsingPCRelativeCalls()) {
3514 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3522 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3530 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3535 if (Subtarget.isUsingPCRelativeCalls()) {
3539 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3540 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3548 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3557 PtrVT, GOTPtr, TGA, TGA);
3559 PtrVT, TLSAddr, TGA);
3560 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3568 EVT PtrVT =
Op.getValueType();
3571 const GlobalValue *GV = GSDN->
getGlobal();
3575 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3576 if (Subtarget.isUsingPCRelativeCalls()) {
3583 MachinePointerInfo());
3588 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3593 return getTOCEntry(DAG,
DL, GA);
3596 unsigned MOHiFlag, MOLoFlag;
3600 if (IsPIC && Subtarget.isSVR4ABI()) {
3604 return getTOCEntry(DAG,
DL, GA);
3616 bool IsStrict =
Op->isStrictFPOpcode();
3617 const SDNodeFlags
Flags =
Op.getNode()->getFlags();
3623 EVT LHSVT =
LHS.getValueType();
3627 if (LHSVT == MVT::f128 ||
3628 (Subtarget.hasSPE() && (LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
3629 (!
Flags.hasNoNaNs() || !
Flags.hasNoInfs()))) {
3630 assert(!Subtarget.hasP9Vector() &&
3631 "SETCC for f128 is already legal under Power9!");
3640 }
else if (LHSVT == MVT::f32 || LHSVT == MVT::f64) {
3644 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3646 if (
Op.getValueType() == MVT::v2i64) {
3649 if (
LHS.getValueType() == MVT::v2i64) {
3657 int ShuffV[] = {1, 0, 3, 2};
3662 dl, MVT::v4i32, Shuff, SetCC32));
3679 if (
C->isAllOnes() ||
C->isZero())
3689 EVT VT =
Op.getValueType();
3697 const SDNodeFlags
Flags =
Op->getFlags();
3703 EVT LHSVT =
LHS.getValueType();
3706 assert(Subtarget.hasSPE() &&
"LowerBR_CC used only for targets with SPE");
3708 if ((LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
Flags.hasNoNaNs() &&
3726 SDNode *
Node =
Op.getNode();
3727 EVT VT =
Node->getValueType(0);
3734 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3738 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3741 if (VT == MVT::i64) {
3760 FprPtr, MachinePointerInfo(SV), MVT::i8);
3771 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3772 InChain = OverflowArea.
getValue(1);
3775 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3805 MachinePointerInfo(SV), MVT::i8);
3818 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3819 MachinePointerInfo(), MVT::i32);
3821 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3825 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3831 Align(8),
false,
true,
nullptr, std::nullopt,
3832 MachinePointerInfo(), MachinePointerInfo());
3837 return Op.getOperand(0);
3842 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3846 "Expecting Inline ASM node.");
3856 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3861 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3862 unsigned NumVals =
Flags.getNumOperandRegisters();
3865 switch (
Flags.getKind()) {
3876 for (; NumVals; --NumVals, ++i) {
3878 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3901 if (Subtarget.isAIXABI()) {
3906 MaybeAlign PointerAlign(PointerSize);
3907 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3910 : MachineMemOperand::MONone;
3917 const Value *TrampolineAddr =
3927 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3928 PointerAlign, MMOFlags);
3930 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3931 MachinePointerInfo(TrampolineAddr, 0));
3935 SDValue TOCFromDescriptorPtr =
3937 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3938 MachinePointerInfo(Func, TOCPointerOffset),
3939 PointerAlign, MMOFlags);
3940 SDValue TrampolineTOCPointer =
3944 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3945 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3951 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3952 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3959 bool isPPC64 = (PtrVT == MVT::i64);
3966 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3972 TargetLowering::CallLoweringInfo CLI(DAG);
3973 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3977 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3978 return CallResult.second;
3983 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3988 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3993 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3994 MachinePointerInfo(SV));
4028 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4031 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4042 MachinePointerInfo(SV), MVT::i8);
4050 MachinePointerInfo(SV, nextOffset), MVT::i8);
4051 nextOffset += StackOffset;
4052 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4055 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4056 MachinePointerInfo(SV, nextOffset));
4057 nextOffset += FrameOffset;
4058 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4061 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4062 MachinePointerInfo(SV, nextOffset));
4067static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4068 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4069 PPC::F11, PPC::F12, PPC::F13};
4074 unsigned PtrByteSize) {
4076 if (Flags.isByVal())
4077 ArgSize = Flags.getByValSize();
4081 if (!Flags.isInConsecutiveRegs())
4082 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4091 unsigned PtrByteSize) {
4092 Align Alignment(PtrByteSize);
4095 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4096 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4097 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4098 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4099 Alignment =
Align(16);
4102 if (Flags.isByVal()) {
4103 auto BVAlign = Flags.getNonZeroByValAlign();
4104 if (BVAlign > PtrByteSize) {
4105 if (BVAlign.value() % PtrByteSize != 0)
4107 "ByVal alignment is not a multiple of the pointer size");
4109 Alignment = BVAlign;
4114 if (Flags.isInConsecutiveRegs()) {
4118 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4132 unsigned PtrByteSize,
unsigned LinkageSize,
4133 unsigned ParamAreaSize,
unsigned &ArgOffset,
4134 unsigned &AvailableFPRs,
4135 unsigned &AvailableVRs) {
4136 bool UseMemory =
false;
4141 ArgOffset =
alignTo(ArgOffset, Alignment);
4144 if (ArgOffset >= LinkageSize + ParamAreaSize)
4149 if (Flags.isInConsecutiveRegsLast())
4150 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4153 if (ArgOffset > LinkageSize + ParamAreaSize)
4158 if (!Flags.isByVal()) {
4159 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4160 if (AvailableFPRs > 0) {
4164 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4165 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4166 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4167 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4168 if (AvailableVRs > 0) {
4180 unsigned NumBytes) {
4184SDValue PPCTargetLowering::LowerFormalArguments(
4188 if (Subtarget.isAIXABI())
4189 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4191 if (Subtarget.is64BitELFABI())
4192 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4194 assert(Subtarget.is32BitELFABI());
4195 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4199SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4235 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4241 const Align PtrAlign(4);
4249 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4250 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4253 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4254 CCValAssign &VA = ArgLocs[i];
4266 RC = &PPC::GPRCRegClass;
4269 if (Subtarget.hasP8Vector())
4270 RC = &PPC::VSSRCRegClass;
4271 else if (Subtarget.hasSPE())
4272 RC = &PPC::GPRCRegClass;
4274 RC = &PPC::F4RCRegClass;
4277 if (Subtarget.hasVSX())
4278 RC = &PPC::VSFRCRegClass;
4279 else if (Subtarget.hasSPE())
4281 RC = &PPC::GPRCRegClass;
4283 RC = &PPC::F8RCRegClass;
4292 RC = &PPC::VRRCRegClass;
4299 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4300 assert(i + 1 < e &&
"No second half of double precision argument");
4305 if (!Subtarget.isLittleEndian())
4307 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4312 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4313 if (ValVT == MVT::i1)
4328 ArgOffset += ArgSize - ObjSize;
4346 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4351 unsigned MinReservedArea = CCByValInfo.getStackSize();
4352 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4368 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4369 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4371 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4374 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4377 unsigned NumFPArgRegs = std::size(FPArgRegs);
4386 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4387 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4390 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4403 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4418 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4422 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4435 if (!MemOps.
empty())
4446 const SDLoc &dl)
const {
4450 else if (
Flags.isZExt())
4457SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4463 bool isELFv2ABI = Subtarget.isELFv2ABI();
4464 bool isLittleEndian = Subtarget.isLittleEndian();
4467 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4470 "fastcc not supported on varargs functions");
4476 unsigned PtrByteSize = 8;
4477 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4480 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4481 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4484 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4485 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4488 const unsigned Num_GPR_Regs = std::size(GPR);
4490 const unsigned Num_VR_Regs = std::size(VR);
4498 bool HasParameterArea = !isELFv2ABI || isVarArg;
4499 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4500 unsigned NumBytes = LinkageSize;
4501 unsigned AvailableFPRs = Num_FPR_Regs;
4502 unsigned AvailableVRs = Num_VR_Regs;
4503 for (
const ISD::InputArg &In : Ins) {
4504 if (
In.Flags.isNest())
4508 LinkageSize, ParamAreaSize, NumBytes,
4509 AvailableFPRs, AvailableVRs))
4510 HasParameterArea =
true;
4517 unsigned ArgOffset = LinkageSize;
4518 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4521 unsigned CurArgIdx = 0;
4522 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4524 bool needsLoad =
false;
4525 EVT ObjectVT = Ins[ArgNo].VT;
4526 EVT OrigVT = Ins[ArgNo].ArgVT;
4528 unsigned ArgSize = ObjSize;
4529 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4530 if (Ins[ArgNo].isOrigArg()) {
4531 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4532 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4537 unsigned CurArgOffset;
4539 auto ComputeArgOffset = [&]() {
4543 ArgOffset =
alignTo(ArgOffset, Alignment);
4544 CurArgOffset = ArgOffset;
4551 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4552 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4557 if (
Flags.isByVal()) {
4558 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4564 ObjSize =
Flags.getByValSize();
4565 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4587 if (HasParameterArea ||
4588 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4595 if (ObjSize < PtrByteSize) {
4599 if (!isLittleEndian) {
4605 if (GPR_idx != Num_GPR_Regs) {
4612 MachinePointerInfo(&*FuncArg), ObjType);
4617 ArgOffset += PtrByteSize;
4626 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4627 if (GPR_idx == Num_GPR_Regs)
4638 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4642 MachinePointerInfo(&*FuncArg, j), ObjType);
4646 ArgOffset += ArgSize;
4655 if (
Flags.isNest()) {
4660 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4661 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4669 if (GPR_idx != Num_GPR_Regs) {
4674 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4677 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4683 ArgSize = PtrByteSize;
4694 if (FPR_idx != Num_FPR_Regs) {
4697 if (ObjectVT == MVT::f32)
4699 Subtarget.hasP8Vector()
4700 ? &PPC::VSSRCRegClass
4701 : &PPC::F4RCRegClass);
4704 ? &PPC::VSFRCRegClass
4705 : &PPC::F8RCRegClass);
4720 if (ObjectVT == MVT::f32) {
4721 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4739 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4740 ArgOffset += ArgSize;
4741 if (
Flags.isInConsecutiveRegsLast())
4742 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4756 if (VR_idx != Num_VR_Regs) {
4773 if (ObjSize < ArgSize && !isLittleEndian)
4774 CurArgOffset += ArgSize - ObjSize;
4777 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4784 unsigned MinReservedArea;
4785 if (HasParameterArea)
4786 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4788 MinReservedArea = LinkageSize;
4805 int Depth = ArgOffset;
4814 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4815 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4827 if (!MemOps.
empty())
4836 unsigned ParamSize) {
4838 if (!isTailCall)
return 0;
4842 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4844 if (SPDiff < FI->getTailCallSPDelta())
4860 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4919 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4922 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4934 const unsigned PtrByteSize = 8;
4938 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4939 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4942 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4943 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4946 const unsigned NumGPRs = std::size(GPR);
4947 const unsigned NumFPRs = 13;
4948 const unsigned NumVRs = std::size(VR);
4949 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4951 unsigned NumBytes = LinkageSize;
4952 unsigned AvailableFPRs = NumFPRs;
4953 unsigned AvailableVRs = NumVRs;
4956 if (Param.Flags.isNest())
continue;
4959 LinkageSize, ParamAreaSize, NumBytes,
4960 AvailableFPRs, AvailableVRs))
4971 auto CalleeArgEnd = CB.
arg_end();
4974 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4975 const Value* CalleeArg = *CalleeArgIter;
4976 const Value* CallerArg = &(*CallerArgIter);
4977 if (CalleeArg == CallerArg)
5003 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5013bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5018 bool isCalleeExternalSymbol)
const {
5021 if (
DisableSCO && !TailCallOpt)
return false;
5024 if (isVarArg)
return false;
5031 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5067 if (!Subtarget.isUsingPCRelativeCalls() &&
5072 if (!Subtarget.isUsingPCRelativeCalls() &&
5100bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5113 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5134 if (!
C)
return nullptr;
5136 int Addr =
C->getZExtValue();
5137 if ((Addr & 3) != 0 ||
5143 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5150struct TailCallArgumentInfo {
5155 TailCallArgumentInfo() =
default;
5165 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5166 SDValue Arg = TailCallArgs[i].Arg;
5167 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5168 int FI = TailCallArgs[i].FrameIdx;
5171 Chain, dl, Arg, FIN,
5180 int SPDiff,
const SDLoc &dl) {
5186 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5187 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5189 NewRetAddrLoc,
true);
5192 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5202 int SPDiff,
unsigned ArgOffset,
5204 int Offset = ArgOffset + SPDiff;
5207 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5209 TailCallArgumentInfo Info;
5211 Info.FrameIdxOp = FIN;
5219SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5224 LROpOut = getReturnAddrFrameIndex(DAG);
5225 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5226 MachinePointerInfo());
5242 Align Alignment = Flags.getNonZeroByValAlign();
5244 Chain, dl, Dst, Src, SizeNode, Alignment, Alignment,
false,
false,
5252 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5276 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5286 if (!MemOpChains2.
empty())
5310SDValue PPCTargetLowering::LowerCallResult(
5318 CCRetInfo.AnalyzeCallResult(
5324 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5325 CCValAssign &VA = RVLocs[i];
5330 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5340 if (!Subtarget.isLittleEndian())
5342 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5408 bool IsStrictFPCall =
false) {
5410 return PPCISD::TC_RETURN;
5412 unsigned RetOpc = 0;
5423 if (Subtarget.usePointerGlueHelper())
5424 RetOpc = PPCISD::BL_LOAD_TOC;
5430 RetOpc = PPCISD::CALL_NOTOC;
5445 RetOpc = PPCISD::CALL;
5446 if (IsStrictFPCall) {
5450 case PPCISD::BCTRL_LOAD_TOC:
5451 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5454 RetOpc = PPCISD::BCTRL_RM;
5456 case PPCISD::BL_LOAD_TOC:
5457 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5459 case PPCISD::CALL_NOTOC:
5460 RetOpc = PPCISD::CALL_NOTOC_RM;
5463 RetOpc = PPCISD::CALL_RM;
5465 case PPCISD::CALL_NOP:
5466 RetOpc = PPCISD::CALL_NOP_RM;
5480 auto isLocalCallee = [&]() {
5496 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5512 return getAIXFuncEntryPointSymbolSDNode(GV);
5519 const char *SymName = S->getSymbol();
5526 return getAIXFuncEntryPointSymbolSDNode(
F);
5532 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5540 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5547 assert(Callee.getNode() &&
"What no callee?");
5553 "Expected a CALLSEQ_STARTSDNode.");
5570 SDValue MTCTROps[] = {Chain, Callee, Glue};
5571 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5572 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5612 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5631 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5632 Alignment, MMOFlags);
5639 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5646 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5658 "Nest parameter is not supported on AIX.");
5673 const SDLoc &dl,
bool hasNest,
5683 Chain = MoveToPhysicalReg.
getValue(0);
5684 Glue = MoveToPhysicalReg.
getValue(1);
5691 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5694 const bool IsPPC64 = Subtarget.isPPC64();
5699 Ops.push_back(Chain);
5703 Ops.push_back(Callee);
5704 else if (Subtarget.usePointerGlueHelper()) {
5705 Ops.push_back(Callee);
5728 Ops.push_back(AddTOC);
5739 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5748 for (
const auto &[
Reg,
N] : RegsToPass)
5766 assert(Mask &&
"Missing call preserved mask for calling convention");
5771 Ops.push_back(Glue);
5774SDValue PPCTargetLowering::FinishCall(
5781 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5782 Subtarget.isAIXABI())
5789 if (!CFlags.IsIndirect)
5791 else if (Subtarget.usesFunctionDescriptors()) {
5792 if (Subtarget.usePointerGlueHelper()) {
5794 CFlags.HasNest, Subtarget);
5800 dl, CFlags.HasNest, Subtarget);
5812 if (CFlags.IsTailCall) {
5820 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5821 "Expecting a global address, external symbol, absolute value, "
5822 "register or an indirect tail call when PC Relative calls are "
5825 assert(CallOpc == PPCISD::TC_RETURN &&
5826 "Unexpected call opcode for a tail call.");
5833 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5834 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5846 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5849 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5869 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5870 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5874bool PPCTargetLowering::isEligibleForTCO(
5879 bool isCalleeExternalSymbol)
const {
5883 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5884 return IsEligibleForTailCallOptimization_64SVR4(
5885 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5886 isCalleeExternalSymbol);
5888 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5916 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5931 "Callee should be an llvm::Function object.");
5934 <<
"\nTCO callee: ");
5941 "site marked musttail");
5948 Callee = LowerGlobalAddress(Callee, DAG);
5951 CallConv, isTailCall, isVarArg, isPatchPoint,
5954 Subtarget.is64BitELFABI() &&
5958 if (Subtarget.isAIXABI())
5959 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5962 assert(Subtarget.isSVR4ABI());
5963 if (Subtarget.isPPC64())
5964 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5966 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5970SDValue PPCTargetLowering::LowerCall_32SVR4(
5981 const bool IsVarArg = CFlags.IsVarArg;
5982 const bool IsTailCall = CFlags.IsTailCall;
5988 const Align PtrAlign(4);
5999 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6007 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6010 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6017 unsigned NumArgs = Outs.
size();
6019 for (
unsigned i = 0; i != NumArgs; ++i) {
6020 MVT ArgVT = Outs[i].VT;
6021 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6026 Outs[i].OrigTy, CCInfo);
6029 ArgFlags, Outs[i].OrigTy, CCInfo);
6034 errs() <<
"Call operand #" << i <<
" has unhandled type "
6047 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6050 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6057 unsigned NumBytes = CCByValInfo.getStackSize();
6071 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6082 bool seenFloatArg =
false;
6087 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6089 ++i, ++RealArgIdx) {
6090 CCValAssign &VA = ArgLocs[i];
6091 SDValue Arg = OutVals[RealArgIdx];
6092 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6094 if (
Flags.isByVal()) {
6099 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6100 CCValAssign &ByValVA = ByValArgLocs[
j++];
6122 Chain = CallSeqStart = NewCallSeqStart;
6141 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6142 bool IsLE = Subtarget.isLittleEndian();
6143 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6146 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6148 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6163 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6172 if (!MemOpChains.
empty())
6178 for (
const auto &[
Reg,
N] : RegsToPass) {
6186 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6189 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6199 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6200 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6205SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6217 return NewCallSeqStart;
6220SDValue PPCTargetLowering::LowerCall_64SVR4(
6227 bool isELFv2ABI = Subtarget.isELFv2ABI();
6228 bool isLittleEndian = Subtarget.isLittleEndian();
6230 bool IsSibCall =
false;
6234 unsigned PtrByteSize = 8;
6247 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6249 assert(!(IsFastCall && CFlags.IsVarArg) &&
6250 "fastcc not supported on varargs functions");
6256 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6257 unsigned NumBytes = LinkageSize;
6258 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6261 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6262 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6265 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6266 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6269 const unsigned NumGPRs = std::size(GPR);
6271 const unsigned NumVRs = std::size(VR);
6277 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6278 if (!HasParameterArea) {
6279 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6280 unsigned AvailableFPRs = NumFPRs;
6281 unsigned AvailableVRs = NumVRs;
6282 unsigned NumBytesTmp = NumBytes;
6283 for (
unsigned i = 0; i !=
NumOps; ++i) {
6284 if (Outs[i].
Flags.isNest())
continue;
6286 PtrByteSize, LinkageSize, ParamAreaSize,
6287 NumBytesTmp, AvailableFPRs, AvailableVRs))
6288 HasParameterArea =
true;
6294 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6299 HasParameterArea =
false;
6302 for (
unsigned i = 0; i !=
NumOps; ++i) {
6303 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6304 EVT ArgVT = Outs[i].VT;
6305 EVT OrigVT = Outs[i].ArgVT;
6311 if (
Flags.isByVal()) {
6312 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6313 if (NumGPRsUsed > NumGPRs)
6314 HasParameterArea =
true;
6321 if (++NumGPRsUsed <= NumGPRs)
6331 if (++NumVRsUsed <= NumVRs)
6335 if (++NumVRsUsed <= NumVRs)
6340 if (++NumFPRsUsed <= NumFPRs)
6344 HasParameterArea =
true;
6351 NumBytes =
alignTo(NumBytes, Alignement);
6354 if (
Flags.isInConsecutiveRegsLast())
6355 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6358 unsigned NumBytesActuallyUsed = NumBytes;
6368 if (HasParameterArea)
6369 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6371 NumBytes = LinkageSize;
6386 if (CFlags.IsTailCall)
6398 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6409 unsigned ArgOffset = LinkageSize;
6415 for (
unsigned i = 0; i !=
NumOps; ++i) {
6417 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6418 EVT ArgVT = Outs[i].VT;
6419 EVT OrigVT = Outs[i].ArgVT;
6428 auto ComputePtrOff = [&]() {
6432 ArgOffset =
alignTo(ArgOffset, Alignment);
6443 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6444 GPR_idx = std::min(GPR_idx, NumGPRs);
6451 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6457 if (
Flags.isByVal()) {
6475 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6476 if (GPR_idx != NumGPRs) {
6478 MachinePointerInfo(), VT);
6482 ArgOffset += PtrByteSize;
6487 if (GPR_idx == NumGPRs &&
Size < 8) {
6489 if (!isLittleEndian) {
6494 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6497 ArgOffset += PtrByteSize;
6506 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6507 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6512 if (
Size < 8 && GPR_idx != NumGPRs) {
6522 if (!isLittleEndian) {
6526 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6532 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6537 ArgOffset += PtrByteSize;
6543 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6546 if (GPR_idx != NumGPRs) {
6547 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6550 MachinePointerInfo(), ObjType);
6554 ArgOffset += PtrByteSize;
6556 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6568 if (
Flags.isNest()) {
6570 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6577 if (GPR_idx != NumGPRs) {
6578 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6583 assert(HasParameterArea &&
6584 "Parameter area must exist to pass an argument in memory.");
6586 true, CFlags.IsTailCall,
false, MemOpChains,
6587 TailCallArguments, dl);
6589 ArgOffset += PtrByteSize;
6592 ArgOffset += PtrByteSize;
6605 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6606 bool NeededLoad =
false;
6609 if (FPR_idx != NumFPRs)
6610 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6613 if (!NeedGPROrStack)
6615 else if (GPR_idx != NumGPRs && !IsFastCall) {
6629 }
else if (!
Flags.isInConsecutiveRegs()) {
6635 }
else if (ArgOffset % PtrByteSize != 0) {
6639 if (!isLittleEndian)
6644 }
else if (
Flags.isInConsecutiveRegsLast()) {
6647 if (!isLittleEndian)
6657 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6665 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6670 assert(HasParameterArea &&
6671 "Parameter area must exist to pass an argument in memory.");
6673 true, CFlags.IsTailCall,
false, MemOpChains,
6674 TailCallArguments, dl);
6681 if (!IsFastCall || NeededLoad) {
6683 Flags.isInConsecutiveRegs()) ? 4 : 8;
6684 if (
Flags.isInConsecutiveRegsLast())
6685 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6705 if (CFlags.IsVarArg) {
6706 assert(HasParameterArea &&
6707 "Parameter area must exist if we have a varargs call.");
6711 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6713 if (VR_idx != NumVRs) {
6715 DAG.
getLoad(MVT::v4f32, dl,
Store, PtrOff, MachinePointerInfo());
6720 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6721 if (GPR_idx == NumGPRs)
6726 DAG.
getLoad(PtrVT, dl,
Store, Ix, MachinePointerInfo());
6734 if (VR_idx != NumVRs) {
6735 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6740 assert(HasParameterArea &&
6741 "Parameter area must exist to pass an argument in memory.");
6743 true, CFlags.IsTailCall,
true, MemOpChains,
6744 TailCallArguments, dl);
6755 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6756 "mismatch in size of parameter area");
6757 (void)NumBytesActuallyUsed;
6759 if (!MemOpChains.
empty())
6765 if (CFlags.IsIndirect) {
6769 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6774 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6784 if (isELFv2ABI && !CFlags.IsPatchPoint)
6785 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6791 for (
const auto &[
Reg,
N] : RegsToPass) {
6796 if (CFlags.IsTailCall && !IsSibCall)
6800 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6801 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6808 "Required alignment greater than stack alignment.");
6828 return RequiredAlign <= 8;
6833 return RequiredAlign <= 4;
6841 State.getMachineFunction().getSubtarget());
6842 const bool IsPPC64 = Subtarget.isPPC64();
6843 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6844 const Align PtrAlign(PtrSize);
6845 const Align StackAlign(16);
6848 if (ValVT == MVT::f128)
6852 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6853 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6855 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6856 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6859 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6860 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6861 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6866 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6875 if (ByValAlign > StackAlign)
6877 "16 are not supported.");
6880 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6884 if (ByValSize == 0) {
6886 State.getStackSize(), RegVT, LocInfo));
6891 unsigned NextReg = State.getFirstUnallocated(GPRs);
6892 while (NextReg != GPRs.
size() &&
6897 State.AllocateStack(PtrSize, PtrAlign);
6898 assert(
Reg &&
"Alocating register unexpectedly failed.");
6900 NextReg = State.getFirstUnallocated(GPRs);
6903 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6904 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6924 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6928 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6947 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6953 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6955 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6956 if (State.isVarArg()) {
6988 const unsigned VecSize = 16;
6989 const Align VecAlign(VecSize);
6991 if (!State.isVarArg()) {
6994 if (
MCRegister VReg = State.AllocateReg(VR)) {
7001 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7006 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7009 while (NextRegIndex != GPRs.
size() &&
7013 State.AllocateStack(PtrSize, PtrAlign);
7014 assert(
Reg &&
"Allocating register unexpectedly failed.");
7016 NextRegIndex = State.getFirstUnallocated(GPRs);
7024 if (
MCRegister VReg = State.AllocateReg(VR)) {
7027 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7028 State.AllocateReg(GPRs);
7029 State.AllocateStack(VecSize, VecAlign);
7033 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7039 if (NextRegIndex == GPRs.
size()) {
7040 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7048 if (GPRs[NextRegIndex] == PPC::R9) {
7049 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7053 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7054 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7055 assert(FirstReg && SecondReg &&
7056 "Allocating R9 or R10 unexpectedly failed.");
7067 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7070 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7072 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7087 assert((IsPPC64 || SVT != MVT::i64) &&
7088 "i64 should have been split for 32-bit codegen.");
7096 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7098 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7100 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7108 return &PPC::VRRCRegClass;
7121 else if (Flags.isZExt())
7133 "Reg must be a valid argument register!");
7134 return LASize + 4 * (
Reg - PPC::R3);
7139 "Reg must be a valid argument register!");
7140 return LASize + 8 * (
Reg - PPC::X3);
7186SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7193 "Unexpected calling convention!");
7201 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7203 const bool IsPPC64 = Subtarget.isPPC64();
7204 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7210 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7211 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7215 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7216 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7217 uint64_t SaveStackPos = CCInfo.getStackSize();
7219 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7223 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7224 CCValAssign &VA = ArgLocs[
I++];
7229 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7230 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7242 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7244 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7250 MachinePointerInfo(),
Align(PtrByteSize));
7256 unsigned StoreSize =
7258 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7261 auto HandleMemLoc = [&]() {
7264 assert((ValSize <= LocSize) &&
7265 "Object size is larger than size of MemLoc");
7268 if (LocSize > ValSize)
7269 CurArgOffset += LocSize - ValSize;
7271 const bool IsImmutable =
7277 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7311 assert(isVarArg &&
"Only use custom memloc for vararg.");
7314 const unsigned OriginalValNo = VA.
getValNo();
7315 (void)OriginalValNo;
7317 auto HandleCustomVecRegLoc = [&]() {
7318 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7319 "Missing custom RegLoc.");
7322 "Unexpected Val type for custom RegLoc.");
7324 "ValNo mismatch between custom MemLoc and RegLoc.");
7328 Subtarget.hasVSX()));
7335 HandleCustomVecRegLoc();
7336 HandleCustomVecRegLoc();
7340 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7342 "Only 2 custom RegLocs expected for 64-bit codegen.");
7343 HandleCustomVecRegLoc();
7344 HandleCustomVecRegLoc();
7388 const unsigned Size =
7400 if (
Flags.isByVal()) {
7404 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7406 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7415 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7417 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7430 CopyFrom.
getValue(1), dl, CopyFrom,
7440 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7443 "RegLocs should be for ByVal argument.");
7445 const CCValAssign RL = ArgLocs[
I++];
7450 if (
Offset != StackSize) {
7452 "Expected MemLoc for remaining bytes.");
7453 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7467 Subtarget.hasVSX()));
7484 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7486 unsigned CallerReservedArea = std::max<unsigned>(
7487 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7493 CallerReservedArea =
7498 int VAListIndex = 0;
7502 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7503 unsigned FixedStackSize =
7504 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7520 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7521 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7523 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7524 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7525 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7531 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7533 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7536 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7537 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7540 MachinePointerInfo MPI =
7550 if (!MemOps.
empty())
7556SDValue PPCTargetLowering::LowerCall_AIX(
7569 "Unexpected calling convention!");
7571 if (CFlags.IsPatchPoint)
7574 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7578 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7585 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7586 const bool IsPPC64 = Subtarget.isPPC64();
7588 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7589 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7590 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7598 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7599 const unsigned NumBytes = std::max<unsigned>(
7600 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7616 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7617 const unsigned ValNo = ArgLocs[
I].getValNo();
7619 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7621 if (
Flags.isByVal()) {
7622 const unsigned ByValSize =
Flags.getByValSize();
7630 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7636 MachinePointerInfo(), VT);
7639 unsigned LoadOffset = 0;
7642 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7645 LoadOffset += PtrByteSize;
7646 const CCValAssign &ByValVA = ArgLocs[
I++];
7648 "Unexpected location for pass-by-value argument.");
7652 if (LoadOffset == ByValSize)
7656 assert(ArgLocs[
I].getValNo() == ValNo &&
7657 "Expected additional location for by-value argument.");
7659 if (ArgLocs[
I].isMemLoc()) {
7660 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7661 const CCValAssign &ByValVA = ArgLocs[
I++];
7662 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7665 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7671 CallSeqStart, MemcpyFlags, DAG, dl);
7680 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7681 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7682 "Unexpected register residue for by-value argument.");
7684 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7688 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7698 "Unexpected load emitted during handling of pass-by-value "
7706 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7711 const CCValAssign &ByValVA = ArgLocs[
I++];
7716 CCValAssign &VA = ArgLocs[
I++];
7741 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7747 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7749 const unsigned OriginalValNo = VA.
getValNo();
7751 unsigned LoadOffset = 0;
7752 auto HandleCustomVecRegLoc = [&]() {
7753 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7754 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7755 "Expected custom RegLoc.");
7756 CCValAssign RegVA = ArgLocs[
I++];
7758 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7764 LoadOffset += PtrByteSize;
7770 HandleCustomVecRegLoc();
7771 HandleCustomVecRegLoc();
7773 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7774 ArgLocs[
I].getValNo() == OriginalValNo) {
7776 "Only 2 custom RegLocs expected for 64-bit codegen.");
7777 HandleCustomVecRegLoc();
7778 HandleCustomVecRegLoc();
7789 DAG.
getStore(Chain, dl, Arg, PtrOff,
7791 Subtarget.getFrameLowering()->getStackAlign()));
7798 "Unexpected register handling for calling convention.");
7804 "Custom register handling only expected for VarArg.");
7809 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7813 else if (Arg.getValueType().getFixedSizeInBits() <
7821 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7822 "Unexpected custom register for argument!");
7823 CCValAssign &GPR1 = VA;
7832 CCValAssign &PeekArg = ArgLocs[
I];
7835 CCValAssign &GPR2 = ArgLocs[
I++];
7843 if (!MemOpChains.
empty())
7848 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7849 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7850 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7851 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7852 const MVT PtrVT = Subtarget.getScalarIntVT();
7853 const unsigned TOCSaveOffset =
7854 Subtarget.getFrameLowering()->getTOCSaveOffset();
7869 for (
auto Reg : RegsToPass) {
7874 const int SPDiff = 0;
7875 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7876 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7884 const Type *RetTy)
const {
7886 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7887 return CCInfo.CheckReturn(
7902 CCInfo.AnalyzeReturn(Outs,
7911 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7912 CCValAssign &VA = RVLocs[i];
7915 SDValue Arg = OutVals[RealResIdx];
7930 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7931 bool isLittleEndian = Subtarget.isLittleEndian();
7934 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7938 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7953 RetOps.push_back(Glue);
7955 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7959PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7964 EVT IntVT =
Op.getValueType();
7968 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7972 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7984 bool isPPC64 = Subtarget.isPPC64();
7985 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7994 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
8000 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8005 bool isPPC64 = Subtarget.isPPC64();
8010 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8016 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8026PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8028 bool isPPC64 = Subtarget.isPPC64();
8033 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8039 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8062 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8064 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8066 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8067 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8074 bool isPPC64 = Subtarget.isPPC64();
8084 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8086 Op.getOperand(0),
Op.getOperand(1));
8092 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8093 Op.getOperand(0),
Op.getOperand(1));
8097 if (
Op.getValueType().isVector())
8098 return LowerVectorLoad(
Op, DAG);
8100 assert(
Op.getValueType() == MVT::i1 &&
8101 "Custom lowering only for i1 loads");
8110 MachineMemOperand *MMO =
LD->getMemOperand();
8114 BasePtr, MVT::i8, MMO);
8122 if (
Op.getOperand(1).getValueType().isVector())
8123 return LowerVectorStore(
Op, DAG);
8125 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8126 "Custom lowering only for i1 stores");
8136 MachineMemOperand *MMO =
ST->getMemOperand();
8145 assert(
Op.getValueType() == MVT::i1 &&
8146 "Custom lowering only for i1 results");
8174 EVT TrgVT =
Op.getValueType();
8198 if (SrcSize == 256) {
8209 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8215 SmallVector<int, 16> ShuffV;
8216 if (Subtarget.isLittleEndian())
8217 for (
unsigned i = 0; i < TrgNumElts; ++i)
8220 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8224 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8237 EVT ResVT =
Op.getValueType();
8238 EVT CmpVT =
Op.getOperand(0).getValueType();
8240 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8246 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8259 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8263 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8280 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8293 if (
LHS.getValueType() == MVT::f32)
8295 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8298 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8306 if (
LHS.getValueType() == MVT::f32)
8308 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8315 if (
LHS.getValueType() == MVT::f32)
8317 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8329 if (
Cmp.getValueType() == MVT::f32)
8331 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8334 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8339 if (
Cmp.getValueType() == MVT::f32)
8341 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8345 if (
Cmp.getValueType() == MVT::f32)
8347 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8351 if (
Cmp.getValueType() == MVT::f32)
8353 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8357 if (
Cmp.getValueType() == MVT::f32)
8359 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8368 case PPCISD::FCTIDZ:
8369 return PPCISD::STRICT_FCTIDZ;
8370 case PPCISD::FCTIWZ:
8371 return PPCISD::STRICT_FCTIWZ;
8372 case PPCISD::FCTIDUZ:
8373 return PPCISD::STRICT_FCTIDUZ;
8374 case PPCISD::FCTIWUZ:
8375 return PPCISD::STRICT_FCTIWUZ;
8377 return PPCISD::STRICT_FCFID;
8378 case PPCISD::FCFIDU:
8379 return PPCISD::STRICT_FCFIDU;
8380 case PPCISD::FCFIDS:
8381 return PPCISD::STRICT_FCFIDS;
8382 case PPCISD::FCFIDUS:
8383 return PPCISD::STRICT_FCFIDUS;
8390 bool IsStrict =
Op->isStrictFPOpcode();
8399 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8401 MVT DestTy =
Op.getSimpleValueType();
8402 assert(Src.getValueType().isFloatingPoint() &&
8403 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8404 DestTy == MVT::i64) &&
8405 "Invalid FP_TO_INT types");
8406 if (Src.getValueType() == MVT::f32) {
8410 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8415 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8421 Opc = IsSigned ? PPCISD::FCTIWZ
8422 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8425 assert((IsSigned || Subtarget.hasFPCVT()) &&
8426 "i64 FP_TO_UINT is supported only with FPCVT");
8427 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8429 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8441void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8443 const SDLoc &dl)
const {
8447 bool IsStrict =
Op->isStrictFPOpcode();
8450 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8451 (IsSigned || Subtarget.hasFPCVT());
8454 MachinePointerInfo MPI =
8463 MachineMemOperand *MMO =
8469 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8473 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8474 !Subtarget.isLittleEndian()) {
8491 const SDLoc &dl)
const {
8494 if (
Op->isStrictFPOpcode())
8501 const SDLoc &dl)
const {
8502 bool IsStrict =
Op->isStrictFPOpcode();
8505 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8506 EVT SrcVT = Src.getValueType();
8507 EVT DstVT =
Op.getValueType();
8510 if (SrcVT == MVT::f128)
8511 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8515 if (SrcVT == MVT::ppcf128) {
8516 if (DstVT == MVT::i32) {
8521 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8532 {Op.getOperand(0), Lo, Hi}, Flags);
8535 {Res.getValue(1), Res}, Flags);
8541 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8565 {Chain, Src, FltOfs}, Flags);
8569 {Chain, Val}, Flags);
8572 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8590 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8591 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8594 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8596 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8597 RLI.Alignment, RLI.MMOFlags(),
8598 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8609bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8614 if (
Op->isStrictFPOpcode())
8619 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8623 Op.getOperand(0).getValueType())) {
8625 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8630 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8631 LD->isNonTemporal())
8633 if (
LD->getMemoryVT() != MemVT)
8643 RLI.Ptr =
LD->getBasePtr();
8644 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8646 "Non-pre-inc AM on PPC?");
8651 RLI.Chain =
LD->getChain();
8652 RLI.MPI =
LD->getPointerInfo();
8653 RLI.IsDereferenceable =
LD->isDereferenceable();
8654 RLI.IsInvariant =
LD->isInvariant();
8655 RLI.Alignment =
LD->getAlign();
8656 RLI.AAInfo =
LD->getAAInfo();
8657 RLI.Ranges =
LD->getRanges();
8659 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8666bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8667 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8674 if (!Subtarget.hasP9Vector() &&
8678 for (SDUse &Use : Origin->
uses()) {
8681 if (
Use.getResNo() != 0)
8708 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8709 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8710 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8711 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8712 if (
Op->isStrictFPOpcode()) {
8714 Chain =
Op.getOperand(0);
8716 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8718 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8726 const SDLoc &dl)
const {
8727 assert((
Op.getValueType() == MVT::f32 ||
8728 Op.getValueType() == MVT::f64) &&
8729 "Invalid floating point type as target of conversion");
8730 assert(Subtarget.hasFPCVT() &&
8731 "Int to FP conversions with direct moves require FPCVT");
8732 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8733 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8736 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8755 for (
unsigned i = 1; i < NumConcat; ++i)
8762 const SDLoc &dl)
const {
8763 bool IsStrict =
Op->isStrictFPOpcode();
8764 unsigned Opc =
Op.getOpcode();
8765 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8768 "Unexpected conversion type");
8769 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8770 "Supports conversions to v2f64/v4f32 only.");
8774 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8777 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8782 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8784 SmallVector<int, 16> ShuffV;
8785 for (
unsigned i = 0; i < WideNumElts; ++i)
8788 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8789 int SaveElts = FourEltRes ? 4 : 2;
8790 if (Subtarget.isLittleEndian())
8791 for (
int i = 0; i < SaveElts; i++)
8792 ShuffV[i * Stride] = i;
8794 for (
int i = 1; i <= SaveElts; i++)
8795 ShuffV[i * Stride - 1] = i - 1;
8803 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8804 EVT ExtVT = Src.getValueType();
8805 if (Subtarget.hasP9Altivec())
8816 {Op.getOperand(0), Extend}, Flags);
8818 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8826 bool IsStrict =
Op->isStrictFPOpcode();
8827 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8832 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8834 EVT InVT = Src.getValueType();
8835 EVT OutVT =
Op.getValueType();
8838 return LowerINT_TO_FPVector(
Op, DAG, dl);
8841 if (
Op.getValueType() == MVT::f128)
8842 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8845 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8848 if (Src.getValueType() == MVT::i1) {
8860 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8861 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8862 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8864 assert((IsSigned || Subtarget.hasFPCVT()) &&
8865 "UINT_TO_FP is supported only with FPCVT");
8867 if (Src.getValueType() == MVT::i64) {
8882 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8883 !
Op->getFlags().hasApproximateFuncs()) {
8923 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8927 DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI, RLI.Alignment,
8928 RLI.MMOFlags(), MMOMetadata(RLI.AAInfo));
8931 }
else if (Subtarget.hasLFIWAX() &&
8932 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8935 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8939 Ops, MVT::i32, MMO);
8942 }
else if (Subtarget.hasFPCVT() &&
8943 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8946 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8950 Ops, MVT::i32, MMO);
8953 }
else if (((Subtarget.hasLFIWAX() &&
8955 (Subtarget.hasFPCVT() &&
8970 "Expected an i32 store");
8976 RLI.Alignment =
Align(4);
8980 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8983 PPCISD::LFIWZX : PPCISD::LFIWAX,
8984 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8985 Ops, MVT::i32, MMO);
8986 Chain =
Bits.getValue(1);
8994 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8998 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9007 assert(Src.getValueType() == MVT::i32 &&
9008 "Unhandled INT_TO_FP type in custom expander!");
9018 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9021 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9031 "Expected an i32 store");
9037 RLI.Alignment =
Align(4);
9042 MMOMetadata(RLI.AAInfo, RLI.Ranges));
9047 Chain = Ld.getValue(1);
9048 if (ReusingLoad && RLI.ResChain) {
9052 assert(Subtarget.isPPC64() &&
9053 "i32->FP without LFIWAX supported only on PPC64");
9062 Chain, dl, Ext64, FIdx,
9068 MVT::f64, dl, Chain, FIdx,
9070 Chain = Ld.getValue(1);
9077 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9081 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9099 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9100 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9101 if (Subtarget.isISA3_0())
9104 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9105 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9108 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9109 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9111 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9129 if (!Subtarget.isISA3_0()) {
9130 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9134 if (Subtarget.isPPC64()) {
9135 if (Subtarget.isISA3_0()) {
9140 PPC::RLDIMI, Dl, MVT::i64,
9145 NewFPSCR =
SDValue(InsertRN, 0);
9152 SDValue Addr = Subtarget.isLittleEndian()
9156 if (Subtarget.isISA3_0()) {
9157 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9159 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9161 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9164 PPC::RLWIMI, Dl, MVT::i32,
9165 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9166 DAG.getTargetConstant(30, Dl, MVT::i32),
9167 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9169 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9172 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9175 if (Subtarget.isISA3_0())
9181 PPC::MTFSF, Dl, MVT::Other,
9209 EVT VT =
Op.getValueType();
9214 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9225 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9229 "Stack slot adjustment is valid only on big endian subtargets!");
9232 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9259 EVT VT =
Op.getValueType();
9263 VT ==
Op.getOperand(1).getValueType() &&
9283 SDValue OutOps[] = { OutLo, OutHi };
9288 EVT VT =
Op.getValueType();
9292 VT ==
Op.getOperand(1).getValueType() &&
9312 SDValue OutOps[] = { OutLo, OutHi };
9318 EVT VT =
Op.getValueType();
9321 VT ==
Op.getOperand(1).getValueType() &&
9341 SDValue OutOps[] = { OutLo, OutHi };
9348 EVT VT =
Op.getValueType();
9355 EVT AmtVT =
Z.getValueType();
9365 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9366 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9378 static const MVT VTys[] = {
9379 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9382 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9385 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9390 EVT CanonicalVT = VTys[SplatSize-1];
9403 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9404 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9413 EVT DestVT = MVT::Other) {
9414 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9423 EVT DestVT = MVT::Other) {
9426 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9438 for (
unsigned i = 0; i != 16; ++i)
9459 EVT VecVT = V->getValueType(0);
9460 bool RightType = VecVT == MVT::v2f64 ||
9461 (HasP8Vector && VecVT == MVT::v4f32) ||
9462 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9466 bool IsSplat =
true;
9467 bool IsLoad =
false;
9473 if (V->isConstant())
9475 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9476 if (V->getOperand(i).isUndef())
9480 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9482 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9484 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9486 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9490 if (V->getOperand(i) != Op0 ||
9491 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9494 return !(IsSplat && IsLoad);
9504 (
Op.getValueType() != MVT::f128))
9509 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9512 if (!Subtarget.isLittleEndian())
9515 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9523 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9524 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9537 APFloat APFloatToConvert = ArgAPFloat;
9538 bool LosesInfo =
true;
9543 ArgAPFloat = APFloatToConvert;
9565 APFloat APFloatToConvert = ArgAPFloat;
9566 bool LosesInfo =
true;
9570 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9579 EVT Ty =
Op->getValueType(0);
9582 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9591 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9595 if (Ty == MVT::v2i64) {
9598 if (MemVT == MVT::i32) {
9600 Opcode = PPCISD::ZEXT_LD_SPLAT;
9602 Opcode = PPCISD::SEXT_LD_SPLAT;
9610 bool IsLittleEndian) {
9616 APInt ConstValue(VTSize, 0);
9620 unsigned BitPos = 0;
9628 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9629 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9633 for (
unsigned J = 0; J < 16; ++J) {
9635 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9637 if (ExtractValue == 0xFF)
9652 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9654 if (Subtarget.hasP10Vector()) {
9655 APInt BitMask(32, 0);
9661 BitMask != 0 && BitMask != 0xffff) {
9663 MachineSDNode *MSDNode =
9675 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9679 APInt APSplatBits, APSplatUndef;
9680 unsigned SplatBitSize = 0;
9682 bool BVNIsConstantSplat =
9684 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9690 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9691 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9694 if ((
Op->getValueType(0) == MVT::v2f64) &&
9697 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9713 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9719 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9728 LowerVecSplatSmallFP(
Op, DAG, BVNIsConstantSplat, SplatBitSize))
9731 bool IsSplat64 =
false;
9733 int32_t SextVal = 0;
9734 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9736 if (SplatBitSize <= 32) {
9738 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9739 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9740 bool P9Vector = Subtarget.hasP9Vector();
9741 int32_t
Hi = P9Vector ? 127 : 15;
9742 int32_t
Lo = P9Vector ? -128 : -16;
9743 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9744 SextVal =
static_cast<int32_t
>(SplatBits);
9748 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9749 unsigned NewOpcode = PPCISD::LD_SPLAT;
9755 const SDValue *InputLoad = &
Op.getOperand(0);
9760 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9761 unsigned ElementSize =
9762 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9764 assert(((ElementSize == 2 * MemorySize)
9765 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9766 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9767 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9768 "Unmatched element size and opcode!\n");
9773 unsigned NumUsesOfInputLD = 128 / ElementSize;
9775 if (BVInOp.isUndef())
9790 if (NumUsesOfInputLD == 1 &&
9791 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9792 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9793 Subtarget.hasLFIWAX()))
9801 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9802 Subtarget.isISA3_1() && ElementSize <= 16)
9805 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9807 Subtarget.hasVSX()) {
9814 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9815 LD->getMemoryVT(),
LD->getMemOperand());
9827 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9829 Subtarget.hasP8Vector()))
9835 unsigned SplatSize = SplatBitSize / 8;
9840 if (SplatBits == 0) {
9842 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9854 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9856 Op.getValueType(), DAG, dl);
9858 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9863 if (Subtarget.hasP9Vector() && SplatSize == 1)
9869 if (SextVal >= -16 && SextVal <= 15) {
9872 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9879 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9885 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9891 switch (SplatSize) {
9895 IID = Intrinsic::ppc_altivec_vupklsb;
9899 IID = Intrinsic::ppc_altivec_vextsb2w;
9903 IID = Intrinsic::ppc_altivec_vextsb2d;
9910 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9919 if (SextVal >= -32 && SextVal <= 31) {
9924 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9925 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9928 if (VT ==
Op.getValueType())
9937 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9951 static const signed char SplatCsts[] = {
9952 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9953 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9956 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9959 int i = SplatCsts[idx];
9963 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9966 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9968 static const unsigned IIDs[] = {
9969 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9970 Intrinsic::ppc_altivec_vslw
9977 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9979 static const unsigned IIDs[] = {
9980 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9981 Intrinsic::ppc_altivec_vsrw
9988 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9989 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9991 static const unsigned IIDs[] = {
9992 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9993 Intrinsic::ppc_altivec_vrlw
10000 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
10002 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
10006 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10008 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
10012 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10014 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
10027 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10028 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10029 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10045 if (LHSID == (1*9+2)*9+3)
return LHS;
10046 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10058 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10059 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10060 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10061 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10064 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10065 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10066 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10067 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10070 for (
unsigned i = 0; i != 16; ++i)
10071 ShufIdxs[i] = (i&3)+0;
10074 for (
unsigned i = 0; i != 16; ++i)
10075 ShufIdxs[i] = (i&3)+4;
10078 for (
unsigned i = 0; i != 16; ++i)
10079 ShufIdxs[i] = (i&3)+8;
10082 for (
unsigned i = 0; i != 16; ++i)
10083 ShufIdxs[i] = (i&3)+12;
10104 const unsigned BytesInVector = 16;
10105 bool IsLE = Subtarget.isLittleEndian();
10109 unsigned ShiftElts = 0, InsertAtByte = 0;
10113 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10114 0, 15, 14, 13, 12, 11, 10, 9};
10115 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10116 1, 2, 3, 4, 5, 6, 7, 8};
10118 ArrayRef<int>
Mask =
N->getMask();
10119 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10131 bool FoundCandidate =
false;
10135 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10138 for (
unsigned i = 0; i < BytesInVector; ++i) {
10139 unsigned CurrentElement =
Mask[i];
10142 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10145 bool OtherElementsInOrder =
true;
10148 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10155 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10156 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10157 OtherElementsInOrder =
false;
10164 if (OtherElementsInOrder) {
10171 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10172 : BigEndianShifts[CurrentElement & 0xF];
10173 Swap = CurrentElement < BytesInVector;
10175 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10176 FoundCandidate =
true;
10181 if (!FoundCandidate)
10191 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10193 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, Shl,
10196 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, V2,
10205 const unsigned NumHalfWords = 8;
10206 const unsigned BytesInVector = NumHalfWords * 2;
10211 bool IsLE = Subtarget.isLittleEndian();
10215 unsigned ShiftElts = 0, InsertAtByte = 0;
10219 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10220 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10223 uint32_t OriginalOrderLow = 0x1234567;
10224 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10227 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10228 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10245 bool FoundCandidate =
false;
10248 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10249 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10251 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10252 uint32_t TargetOrder = 0x0;
10259 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10260 TargetOrder = OriginalOrderLow;
10264 if (MaskOneElt == VINSERTHSrcElem &&
10265 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10266 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10267 FoundCandidate =
true;
10273 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10275 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10277 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10278 : BigEndianShifts[MaskOneElt & 0x7];
10279 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10280 Swap = MaskOneElt < NumHalfWords;
10281 FoundCandidate =
true;
10287 if (!FoundCandidate)
10299 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10302 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10307 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10322 auto ShuffleMask = SVN->
getMask();
10337 ShuffleMask = CommutedSV->
getMask();
10346 APInt APSplatValue, APSplatUndef;
10347 unsigned SplatBitSize;
10350 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10362 bool IsLE = Subtarget.isLittleEndian();
10363 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10364 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10365 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10367 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10368 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10369 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10377 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10378 SplatVal |= (SplatVal << SplatBitSize);
10381 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10392 assert(
Op.getValueType() == MVT::v1i128 &&
10393 "Only set v1i128 as custom, other type shouldn't reach here!");
10398 if (SHLAmt % 8 == 0) {
10399 std::array<int, 16>
Mask;
10400 std::iota(
Mask.begin(),
Mask.end(), 0);
10401 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10430 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10435 V1 =
Op.getOperand(0);
10436 V2 =
Op.getOperand(1);
10438 EVT VT =
Op.getValueType();
10439 bool isLittleEndian = Subtarget.isLittleEndian();
10441 unsigned ShiftElts, InsertAtByte;
10447 bool IsPermutedLoad =
false;
10449 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10459 if (IsPermutedLoad) {
10460 assert((isLittleEndian || IsFourByte) &&
10461 "Unexpected size for permuted load on big endian target");
10462 SplatIdx += IsFourByte ? 2 : 1;
10463 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10464 "Splat of a value outside of the loaded memory");
10469 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10472 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10474 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10478 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10491 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10494 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10503 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10506 if (Subtarget.hasP9Vector() &&
10516 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10518 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10522 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10527 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10529 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10530 return SplatInsertNode;
10533 if (Subtarget.hasP9Altivec()) {
10535 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10538 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10542 if (Subtarget.hasVSX() &&
10550 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10555 if (Subtarget.hasVSX() &&
10563 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10568 if (Subtarget.hasP9Vector()) {
10588 if (Subtarget.hasVSX()) {
10609 if (V2.isUndef()) {
10622 (Subtarget.hasP8Altivec() && (
10633 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10643 (Subtarget.hasP8Altivec() && (
10651 ArrayRef<int> PermMask = SVOp->
getMask();
10654 unsigned PFIndexes[4];
10655 bool isFourElementShuffle =
true;
10656 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10658 unsigned EltNo = 8;
10659 for (
unsigned j = 0;
j != 4; ++
j) {
10660 if (PermMask[i * 4 + j] < 0)
10663 unsigned ByteSource = PermMask[i * 4 +
j];
10664 if ((ByteSource & 3) != j) {
10665 isFourElementShuffle =
false;
10670 EltNo = ByteSource / 4;
10671 }
else if (EltNo != ByteSource / 4) {
10672 isFourElementShuffle =
false;
10676 PFIndexes[i] = EltNo;
10684 if (isFourElementShuffle) {
10686 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10687 PFIndexes[2] * 9 + PFIndexes[3];
10690 unsigned Cost = (PFEntry >> 30);
10710 if (V2.isUndef()) V2 =
V1;
10712 return LowerVPERM(
Op, DAG, PermMask, VT,
V1, V2);
10718 unsigned Opcode = PPCISD::VPERM;
10721 bool NeedSwap =
false;
10722 bool isLittleEndian = Subtarget.isLittleEndian();
10723 bool isPPC64 = Subtarget.isPPC64();
10725 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10727 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10728 "XXPERM instead\n");
10729 Opcode = PPCISD::XXPERM;
10734 if ((!isLittleEndian && !V2->
hasOneUse() &&
V1->hasOneUse()) ||
10735 (isLittleEndian && !
V1->hasOneUse() && V2->
hasOneUse())) {
10737 NeedSwap = !NeedSwap;
10751 bool V1HasXXSWAPD =
V1->getOperand(0)->getOpcode() == PPCISD::XXSWAPD;
10772 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10774 if (V1HasXXSWAPD) {
10777 else if (SrcElt < 16)
10780 if (V2HasXXSWAPD) {
10783 else if (SrcElt > 15)
10792 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10793 if (isLittleEndian)
10795 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10798 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10801 if (V1HasXXSWAPD) {
10802 dl = SDLoc(
V1->getOperand(0));
10803 V1 =
V1->getOperand(0)->getOperand(1);
10805 if (V2HasXXSWAPD) {
10810 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10811 if (ValType != MVT::v2f64)
10817 ShufflesHandledWithVPERM++;
10821 if (Opcode == PPCISD::XXPERM) {
10822 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10824 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10827 dbgs() <<
"With the following permute control vector:\n";
10831 if (Opcode == PPCISD::XXPERM)
10832 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10836 if (isLittleEndian)
10840 DAG.
getNode(Opcode, dl,
V1.getValueType(),
V1, V2, VPermMask);
10842 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10854 switch (IntrinsicID) {
10858 case Intrinsic::ppc_altivec_vcmpbfp_p:
10862 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10866 case Intrinsic::ppc_altivec_vcmpequb_p:
10870 case Intrinsic::ppc_altivec_vcmpequh_p:
10874 case Intrinsic::ppc_altivec_vcmpequw_p:
10878 case Intrinsic::ppc_altivec_vcmpequd_p:
10879 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10885 case Intrinsic::ppc_altivec_vcmpneb_p:
10886 case Intrinsic::ppc_altivec_vcmpneh_p:
10887 case Intrinsic::ppc_altivec_vcmpnew_p:
10888 case Intrinsic::ppc_altivec_vcmpnezb_p:
10889 case Intrinsic::ppc_altivec_vcmpnezh_p:
10890 case Intrinsic::ppc_altivec_vcmpnezw_p:
10891 if (Subtarget.hasP9Altivec()) {
10892 switch (IntrinsicID) {
10895 case Intrinsic::ppc_altivec_vcmpneb_p:
10898 case Intrinsic::ppc_altivec_vcmpneh_p:
10901 case Intrinsic::ppc_altivec_vcmpnew_p:
10904 case Intrinsic::ppc_altivec_vcmpnezb_p:
10907 case Intrinsic::ppc_altivec_vcmpnezh_p:
10910 case Intrinsic::ppc_altivec_vcmpnezw_p:
10918 case Intrinsic::ppc_altivec_vcmpgefp_p:
10922 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10926 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10930 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10934 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10938 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10939 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10945 case Intrinsic::ppc_altivec_vcmpgtub_p:
10949 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10953 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10957 case Intrinsic::ppc_altivec_vcmpgtud_p:
10958 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10965 case Intrinsic::ppc_altivec_vcmpequq:
10966 case Intrinsic::ppc_altivec_vcmpgtsq:
10967 case Intrinsic::ppc_altivec_vcmpgtuq:
10968 if (!Subtarget.isISA3_1())
10970 switch (IntrinsicID) {
10973 case Intrinsic::ppc_altivec_vcmpequq:
10976 case Intrinsic::ppc_altivec_vcmpgtsq:
10979 case Intrinsic::ppc_altivec_vcmpgtuq:
10986 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10987 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10988 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10989 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10990 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10991 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10992 if (Subtarget.hasVSX()) {
10993 switch (IntrinsicID) {
10994 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10997 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11000 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11003 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11006 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11009 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11019 case Intrinsic::ppc_altivec_vcmpbfp:
11022 case Intrinsic::ppc_altivec_vcmpeqfp:
11025 case Intrinsic::ppc_altivec_vcmpequb:
11028 case Intrinsic::ppc_altivec_vcmpequh:
11031 case Intrinsic::ppc_altivec_vcmpequw:
11034 case Intrinsic::ppc_altivec_vcmpequd:
11035 if (Subtarget.hasP8Altivec())
11040 case Intrinsic::ppc_altivec_vcmpneb:
11041 case Intrinsic::ppc_altivec_vcmpneh:
11042 case Intrinsic::ppc_altivec_vcmpnew:
11043 case Intrinsic::ppc_altivec_vcmpnezb:
11044 case Intrinsic::ppc_altivec_vcmpnezh:
11045 case Intrinsic::ppc_altivec_vcmpnezw:
11046 if (Subtarget.hasP9Altivec())
11047 switch (IntrinsicID) {
11050 case Intrinsic::ppc_altivec_vcmpneb:
11053 case Intrinsic::ppc_altivec_vcmpneh:
11056 case Intrinsic::ppc_altivec_vcmpnew:
11059 case Intrinsic::ppc_altivec_vcmpnezb:
11062 case Intrinsic::ppc_altivec_vcmpnezh:
11065 case Intrinsic::ppc_altivec_vcmpnezw:
11072 case Intrinsic::ppc_altivec_vcmpgefp:
11075 case Intrinsic::ppc_altivec_vcmpgtfp:
11078 case Intrinsic::ppc_altivec_vcmpgtsb:
11081 case Intrinsic::ppc_altivec_vcmpgtsh:
11084 case Intrinsic::ppc_altivec_vcmpgtsw:
11087 case Intrinsic::ppc_altivec_vcmpgtsd:
11088 if (Subtarget.hasP8Altivec())
11093 case Intrinsic::ppc_altivec_vcmpgtub:
11096 case Intrinsic::ppc_altivec_vcmpgtuh:
11099 case Intrinsic::ppc_altivec_vcmpgtuw:
11102 case Intrinsic::ppc_altivec_vcmpgtud:
11103 if (Subtarget.hasP8Altivec())
11108 case Intrinsic::ppc_altivec_vcmpequq_p:
11109 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11110 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11111 if (!Subtarget.isISA3_1())
11113 switch (IntrinsicID) {
11116 case Intrinsic::ppc_altivec_vcmpequq_p:
11119 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11122 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11136 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11142 auto MapNodeWithSplatVector =
11143 [&](
unsigned Opcode,
11144 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11149 Ops.append(ExtraOps.begin(), ExtraOps.end());
11150 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11153 switch (IntrinsicID) {
11154 case Intrinsic::thread_pointer:
11156 if (Subtarget.isPPC64())
11160 case Intrinsic::ppc_rldimi: {
11161 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11163 APInt
Mask =
Op.getConstantOperandAPInt(4);
11165 return Op.getOperand(2);
11166 if (
Mask.isAllOnes())
11169 unsigned MB = 0, ME = 0;
11173 if (ME < 63 - SH) {
11176 }
else if (ME > 63 - SH) {
11182 {Op.getOperand(2), Src,
11183 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11184 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11188 case Intrinsic::ppc_rlwimi: {
11189 APInt
Mask =
Op.getConstantOperandAPInt(4);
11191 return Op.getOperand(2);
11192 if (
Mask.isAllOnes())
11195 unsigned MB = 0, ME = 0;
11199 PPC::RLWIMI, dl, MVT::i32,
11200 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11201 DAG.getTargetConstant(MB, dl, MVT::i32),
11202 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11206 case Intrinsic::ppc_bcdshift:
11207 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11208 case Intrinsic::ppc_bcdshiftround:
11209 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11210 case Intrinsic::ppc_bcdtruncate:
11211 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11212 case Intrinsic::ppc_bcdunsignedtruncate:
11213 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11214 case Intrinsic::ppc_bcdunsignedshift:
11215 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11217 case Intrinsic::ppc_rlwnm: {
11218 if (
Op.getConstantOperandVal(3) == 0)
11220 unsigned MB = 0, ME = 0;
11225 {Op.getOperand(1), Op.getOperand(2),
11226 DAG.getTargetConstant(MB, dl, MVT::i32),
11227 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11231 case Intrinsic::ppc_mma_disassemble_acc: {
11232 if (Subtarget.isISAFuture()) {
11233 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11244 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11245 Subtarget.isLittleEndian() ? Value2 :
Value,
11246 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11250 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11251 Subtarget.isLittleEndian() ? Value2 :
Value,
11252 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11256 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11257 Subtarget.isLittleEndian() ?
Value : Value2,
11258 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11262 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11263 Subtarget.isLittleEndian() ?
Value : Value2,
11264 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11271 case Intrinsic::ppc_vsx_disassemble_pair: {
11274 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11276 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11279 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11281 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11282 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11290 case Intrinsic::ppc_build_dmr: {
11293 for (
int i = 1; i < 9; i += 2) {
11301 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11308 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11309 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11311 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11312 "Specify P of 0 or 1 for lower or upper 512 bytes");
11313 unsigned HiLo = Idx->getSExtValue();
11317 Opcode = PPC::DMXXEXTFDMR512;
11318 Subx = PPC::sub_wacc_lo;
11320 Opcode = PPC::DMXXEXTFDMR512_HI;
11321 Subx = PPC::sub_wacc_hi;
11324 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11328 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11332 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11333 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11335 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11336 "Specify a dmr row pair 0-3");
11337 unsigned IdxVal = Idx->getSExtValue();
11341 Subx = PPC::sub_dmrrowp0;
11344 Subx = PPC::sub_dmrrowp1;
11347 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11350 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11354 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11360 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11364 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11365 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11367 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11368 "Specify P of 0 or 1 for lower or upper 512 bytes");
11369 unsigned HiLo = Idx->getSExtValue();
11373 Opcode = PPCISD::INST512;
11374 Subx = PPC::sub_wacc_lo;
11376 Opcode = PPCISD::INST512HI;
11377 Subx = PPC::sub_wacc_hi;
11383 Op.getOperand(1), Wacc, SubReg),
11387 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11388 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11390 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11391 "Specify a dmr row pair 0-3");
11392 unsigned IdxVal = Idx->getSExtValue();
11396 Subx = PPC::sub_dmrrowp0;
11399 Subx = PPC::sub_dmrrowp1;
11402 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11405 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11411 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11413 Op.getOperand(1), DMRRowp, SubReg),
11417 case Intrinsic::ppc_mma_xxmfacc:
11418 case Intrinsic::ppc_mma_xxmtacc: {
11420 if (!Subtarget.isISAFuture())
11431 case Intrinsic::ppc_unpack_longdouble: {
11433 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11434 "Argument of long double unpack must be 0 or 1!");
11437 Idx->getValueType(0)));
11440 case Intrinsic::ppc_compare_exp_lt:
11441 case Intrinsic::ppc_compare_exp_gt:
11442 case Intrinsic::ppc_compare_exp_eq:
11443 case Intrinsic::ppc_compare_exp_uo: {
11445 switch (IntrinsicID) {
11446 case Intrinsic::ppc_compare_exp_lt:
11449 case Intrinsic::ppc_compare_exp_gt:
11452 case Intrinsic::ppc_compare_exp_eq:
11455 case Intrinsic::ppc_compare_exp_uo:
11461 PPC::SELECT_CC_I4, dl, MVT::i32,
11462 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11463 Op.getOperand(1), Op.getOperand(2)),
11465 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11466 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11469 case Intrinsic::ppc_test_data_class: {
11470 EVT OpVT =
Op.getOperand(1).getValueType();
11471 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11472 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11485 {Op.getOperand(2), Op.getOperand(1)}),
11487 if (Subtarget.isISA3_1()) {
11494 TestDataClass, SubRegIdx),
11497 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11503 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11504 DAG.getConstant(0, dl, MVT::i32),
11505 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11508 case Intrinsic::ppc_fnmsub: {
11509 EVT VT =
Op.getOperand(1).getValueType();
11510 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11515 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11516 Op.getOperand(2),
Op.getOperand(3));
11518 case Intrinsic::ppc_convert_f128_to_ppcf128:
11519 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11520 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11521 ? RTLIB::CONVERT_PPCF128_F128
11522 : RTLIB::CONVERT_F128_PPCF128;
11524 std::pair<SDValue, SDValue>
Result =
11525 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11529 case Intrinsic::ppc_maxfe:
11530 case Intrinsic::ppc_maxfl:
11531 case Intrinsic::ppc_maxfs:
11532 case Intrinsic::ppc_minfe:
11533 case Intrinsic::ppc_minfl:
11534 case Intrinsic::ppc_minfs: {
11535 EVT VT =
Op.getValueType();
11538 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11539 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11542 if (IntrinsicID == Intrinsic::ppc_minfe ||
11543 IntrinsicID == Intrinsic::ppc_minfl ||
11544 IntrinsicID == Intrinsic::ppc_minfs)
11565 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11566 Op.getOperand(1),
Op.getOperand(2),
11577 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11585 switch (
Op.getConstantOperandVal(1)) {
11590 Bitx = PPC::sub_eq;
11591 SetOp = PPCISD::SETBC;
11596 Bitx = PPC::sub_eq;
11597 SetOp = PPCISD::SETBCR;
11602 Bitx = PPC::sub_lt;
11603 SetOp = PPCISD::SETBC;
11608 Bitx = PPC::sub_lt;
11609 SetOp = PPCISD::SETBCR;
11614 if (Subtarget.isISA3_1()) {
11619 CR6Reg, SubRegIdx, GlueOp),
11621 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11649 switch (
Op.getConstantOperandVal(ArgStart)) {
11650 case Intrinsic::ppc_cfence: {
11651 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11652 SDValue Val =
Op.getOperand(ArgStart + 1);
11654 if (Ty == MVT::i128) {
11659 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11662 Opcode,
DL, MVT::Other,
11667 case Intrinsic::ppc_disassemble_dmr: {
11669 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11670 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11671 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11682 if (!Subtarget.isPPC64())
11685 if (Subtarget.hasP9Vector()) {
11692 int VectorIndex = 0;
11693 if (Subtarget.isLittleEndian())
11703 auto CreateRotateInsert =
11704 [&](
unsigned Opcode, MVT VT,
SDValue Dest,
SDValue Src,
unsigned RotAmt,
11705 unsigned MaskBegin,
11706 std::optional<unsigned> MaskEnd = std::nullopt) ->
SDValue {
11710 if (MaskEnd.has_value())
11722 CreateRotateInsert(PPC::RLWIMI, MVT::i32, Rot, Val32, 24, 0, 7);
11724 return CreateRotateInsert(PPC::RLWIMI, MVT::i32,
Swap, Val32, 24, 16, 23);
11737 return CreateRotateInsert(PPC::RLDIMI, MVT::i64, HiSwap, LoSwap, 32, 0);
11745 "Expecting an atomic compare-and-swap here.");
11748 EVT MemVT = AtomicNode->getMemoryVT();
11766 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11767 Ops.push_back(AtomicNode->getOperand(i));
11769 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11770 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11772 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11779 EVT MemVT =
N->getMemoryVT();
11781 "Expect quadword atomic operations");
11783 unsigned Opc =
N->getOpcode();
11788 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11791 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11792 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11793 Ops.push_back(
N->getOperand(
I));
11795 Ops, MemVT,
N->getMemOperand());
11802 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11809 SDVTList Tys = DAG.
getVTList(MVT::Other);
11812 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11818 Ops.push_back(ValLo);
11819 Ops.push_back(ValHi);
11820 Ops.push_back(
N->getOperand(2));
11822 N->getMemOperand());
11834 enum DataClassMask {
11836 DC_NEG_INF = 1 << 4,
11837 DC_POS_INF = 1 << 5,
11838 DC_NEG_ZERO = 1 << 2,
11839 DC_POS_ZERO = 1 << 3,
11840 DC_NEG_SUBNORM = 1,
11841 DC_POS_SUBNORM = 1 << 1,
11844 EVT VT =
Op.getValueType();
11846 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11847 : VT == MVT::f64 ? PPC::XSTSTDCDP
11858 return DAG.
getNOT(Dl, Rev, MVT::i1);
11865 TestOp, Dl, MVT::i32,
11867 DC_NEG_ZERO | DC_POS_ZERO |
11868 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11874 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11880 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11885 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11898 bool IsQuiet = Mask &
fcQNan;
11904 if (VT == MVT::f128) {
11908 QuietMask = 0x8000;
11909 }
else if (VT == MVT::f64) {
11910 if (Subtarget.isPPC64()) {
11921 QuietMask = 0x80000;
11922 }
else if (VT == MVT::f32) {
11924 QuietMask = 0x400000;
11940 unsigned NativeMask = 0;
11942 NativeMask |= DC_NAN;
11944 NativeMask |= DC_NEG_INF;
11946 NativeMask |= DC_POS_INF;
11948 NativeMask |= DC_NEG_ZERO;
11950 NativeMask |= DC_POS_ZERO;
11952 NativeMask |= DC_NEG_SUBNORM;
11954 NativeMask |= DC_POS_SUBNORM;
11957 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11959 TestOp, Dl, MVT::i32,
11968 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11970 uint64_t RHSC =
Op.getConstantOperandVal(1);
11973 if (
LHS.getValueType() == MVT::ppcf128) {
11997 bool Future = Subtarget.isISAFuture();
12000 "Mask predication not supported");
12003 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
12004 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
12008 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
12011 VPLD->getMemoryVT(), VPLD->getMemOperand());
12018 "Mask predication not supported");
12023 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
12024 bool Future = Subtarget.isISAFuture();
12025 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
12028 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
12031 SDVTList Tys = DAG.
getVTList(MVT::Other);
12034 VPST->getMemoryVT(), VPST->getMemOperand());
12045 "Unexpected partial reduction");
12068 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
12070 int64_t
IntVal =
Op.getConstantOperandVal(0);
12071 if (IntVal >= -16 && IntVal <= 15)
12077 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
12084 MMOMetadata(RLI.AAInfo, RLI.Ranges));
12087 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
12091 return Bits.getValue(0);
12107 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12112 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12120 MachinePointerInfo());
12127 return DAG.
getLoad(
Op.getValueType(), dl,
Store, FIdx, MachinePointerInfo());
12133 "Should only be called for ISD::INSERT_VECTOR_ELT");
12137 EVT VT =
Op.getValueType();
12142 if (VT == MVT::v2f64 &&
C)
12145 if (Subtarget.hasP9Vector()) {
12154 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12160 BitcastLoad,
Op.getOperand(2));
12161 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12165 if (Subtarget.isISA3_1()) {
12166 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12170 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12171 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12181 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12184 unsigned InsertAtElement =
C->getZExtValue();
12185 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12186 if (Subtarget.isLittleEndian()) {
12187 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12189 return DAG.
getNode(PPCISD::VECINSERT, dl, VT,
V1, Mtvsrz,
12201 EVT VT =
Op.getValueType();
12202 bool IsV1024i1 = VT == MVT::v1024i1;
12203 bool IsV2048i1 = VT == MVT::v2048i1;
12207 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12209 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12210 "Dense Math support required.");
12211 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12220 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12221 MachineMemOperand *NewMMO =
12229 DAG.
getVTList(MVT::v256i1, MVT::Other),
12230 LoadOps, MVT::v256i1, NewMMO);
12235 if (Subtarget.isLittleEndian()) {
12236 std::reverse(Loads.
begin(), Loads.
end());
12237 std::reverse(LoadChains.
begin(), LoadChains.
end());
12249 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12255 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12258 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12267 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12270 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12275 {RC, Lo, LoSub, Hi, HiSub}),
12285 EVT VT =
Op.getValueType();
12287 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12288 return LowerDMFVectorLoad(
Op, DAG);
12290 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12294 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12295 "Type unsupported without MMA");
12296 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12297 "Type unsupported without paired vector support");
12301 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12310 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12312 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12321 if (Subtarget.isLittleEndian()) {
12322 std::reverse(Loads.
begin(), Loads.
end());
12323 std::reverse(LoadChains.
begin(), LoadChains.
end());
12327 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12343 bool IsV1024i1 = VT == MVT::v1024i1;
12344 bool IsV2048i1 = VT == MVT::v2048i1;
12348 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12350 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12351 "Dense Math support required.");
12352 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12354 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12357 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12362 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12366 MachineSDNode *ExtNode =
12370 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12376 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12382 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12388 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12393 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12398 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12403 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12407 MachineSDNode *ExtNode =
12408 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12412 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12415 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12419 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12424 if (Subtarget.isLittleEndian())
12427 SDVTList Tys = DAG.
getVTList(MVT::Other);
12429 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12433 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12434 MachineMemOperand *NewMMO =
12443 MVT::v256i1, NewMMO);
12459 EVT StoreVT =
Value.getValueType();
12461 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12462 return LowerDMFVectorStore(
Op, DAG);
12464 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12468 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12469 "Type unsupported without MMA");
12470 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12471 "Type unsupported without paired vector support");
12475 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12483 unsigned NumVecs = 2;
12484 if (StoreVT == MVT::v512i1) {
12485 if (Subtarget.isISAFuture()) {
12486 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12488 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12491 Value2 =
SDValue(ExtNode, 1);
12496 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12497 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12499 if (Subtarget.isISAFuture()) {
12500 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12501 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12502 Idx > 1 ? Value2 :
Value,
12505 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12509 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12523 if (
Op.getValueType() == MVT::v4i32) {
12540 LHS,
RHS, DAG, dl, MVT::v4i32);
12543 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12548 }
else if (
Op.getValueType() == MVT::v16i8) {
12550 bool isLittleEndian = Subtarget.isLittleEndian();
12554 LHS,
RHS, DAG, dl, MVT::v8i16);
12559 LHS,
RHS, DAG, dl, MVT::v8i16);
12567 for (
unsigned i = 0; i != 8; ++i) {
12568 if (isLittleEndian) {
12570 Ops[i*2+1] = 2*i+16;
12573 Ops[i*2+1] = 2*i+1+16;
12576 if (isLittleEndian)
12586 bool IsStrict =
Op->isStrictFPOpcode();
12587 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12588 !Subtarget.hasP9Vector())
12598 "Should only be called for ISD::FP_EXTEND");
12602 if (
Op.getValueType() != MVT::v2f64 ||
12603 Op.getOperand(0).getValueType() != MVT::v2f32)
12615 "Node should have 2 operands with second one being a constant!");
12627 int DWord = Idx >> 1;
12630 if (Subtarget.isLittleEndian())
12633 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12647 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12649 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12650 LD->getMemoryVT(),
LD->getMemOperand());
12655 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12660 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12662 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12663 LD->getMemoryVT(),
LD->getMemOperand());
12664 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12675 if (STI.useCRBits())
12692 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12693 if (STI.useCRBits())
12701 SDNode *
N =
Op.getNode();
12702 EVT VT =
N->getValueType(0);
12703 EVT CarryType =
N->getValueType(1);
12704 unsigned Opc =
N->getOpcode();
12706 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12708 N->getOperand(0),
N->getOperand(1));
12720 SDNode *
N =
Op.getNode();
12721 unsigned Opc =
N->getOpcode();
12722 EVT VT =
N->getValueType(0);
12723 EVT CarryType =
N->getValueType(1);
12724 SDValue CarryOp =
N->getOperand(2);
12726 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12732 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12746 EVT VT =
Op.getNode()->getValueType(0);
12772 EVT VT =
Op.getNode()->getValueType(0);
12804 EVT OpVT =
LHS.getValueType();
12805 EVT VT =
Op.getValueType();
12820 unsigned Opcode = PPCISD::SUBC;
12830 Opcode = PPCISD::ADDC;
12837 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12844 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12864 EVT OpVT =
A.getValueType();
12865 EVT ResVT =
Op.getValueType();
12870 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12880 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12908 EVT VT =
LHS.getValueType();
12909 EVT ResVT =
Op.getValueType();
12912 if (Subtarget.isISA3_0())
12916 bool Is64BitCmp = (VT == MVT::i64);
12921 bool Use64BitOps = Subtarget.isPPC64();
12924 unsigned CmpOpc = Is64BitCmp ? PPC::CMPD : PPC::CMPW;
12935 unsigned MFOCRFOpc = Use64BitOps ? PPC::MFOCRF8 : PPC::MFOCRF;
12936 EVT MFVT = Use64BitOps ? MVT::i64 : MVT::i32;
12947 unsigned RLWinmOpc = Use64BitOps ? PPC::RLWINM8 : PPC::RLWINM;
12965 unsigned SubOpc = Use64BitOps ? PPC::SUBF8 : PPC::SUBF;
12979 switch (
Op.getOpcode()) {
13000 return LowerSSUBO(
Op, DAG);
13002 return LowerSADDO(
Op, DAG);
13014 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
13035 return LowerSET_ROUNDING(
Op, DAG);
13042 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
13043 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
13055 return LowerFP_ROUND(
Op, DAG);
13069 return LowerINTRINSIC_VOID(
Op, DAG);
13071 return LowerBSWAP(
Op, DAG);
13073 return LowerATOMIC_CMP_SWAP(
Op, DAG);
13075 return LowerATOMIC_LOAD_STORE(
Op, DAG);
13077 return LowerIS_FPCLASS(
Op, DAG);
13080 return LowerADDSUBO(
Op, DAG);
13083 return LowerADDSUBO_CARRY(
Op, DAG);
13085 return LowerUCMP(
Op, DAG);
13087 return LowerABDU(
Op, DAG);
13089 return LowerSCMP(
Op, DAG);
13095 if (
Op->getFlags().hasNoFPExcept())
13099 return LowerVP_LOAD(
Op, DAG);
13100 case ISD::VP_STORE:
13101 return LowerVP_STORE(
Op, DAG);
13103 return LowerPartialReduce(
Op, DAG);
13111 switch (
N->getOpcode()) {
13113 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
13130 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
13133 assert(
N->getValueType(0) == MVT::i1 &&
13134 "Unexpected result type for CTR decrement intrinsic");
13136 N->getValueType(0));
13146 switch (
N->getConstantOperandVal(0)) {
13147 case Intrinsic::ppc_pack_longdouble:
13149 N->getOperand(2),
N->getOperand(1)));
13151 case Intrinsic::ppc_maxfe:
13152 case Intrinsic::ppc_minfe:
13153 case Intrinsic::ppc_fnmsub:
13154 case Intrinsic::ppc_convert_f128_to_ppcf128:
13161 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
13164 EVT VT =
N->getValueType(0);
13166 if (VT == MVT::i64) {
13179 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
13183 Results.push_back(LoweredValue);
13184 if (
N->isStrictFPOpcode())
13189 if (!
N->getValueType(0).isVector())
13222 return Builder.CreateIntrinsicWithoutFolding(Id, {});
13228 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
13230 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13231 "Only 8/16/32/64-bit atomic loads supported");
13237 IntID = Intrinsic::ppc_lbarx;
13238 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13241 IntID = Intrinsic::ppc_lharx;
13242 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13245 IntID = Intrinsic::ppc_lwarx;
13248 IntID = Intrinsic::ppc_ldarx;
13252 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
13254 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13265 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13266 "Only 8/16/32/64-bit atomic loads supported");
13272 IntID = Intrinsic::ppc_stbcx;
13273 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13276 IntID = Intrinsic::ppc_sthcx;
13277 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13280 IntID = Intrinsic::ppc_stwcx;
13283 IntID = Intrinsic::ppc_stdcx;
13287 if (SZ == 8 || SZ == 16)
13288 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13290 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13292 return Builder.CreateXor(
Call, Builder.getInt32(1));
13315 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::ppc_cfence,
13325 unsigned BinOpcode,
13326 unsigned CmpOpcode,
13327 unsigned CmpPred)
const {
13332 unsigned AtomicSize =
MI.getOperand(3).getImm();
13334 auto LoadMnemonic = PPC::LDARX;
13335 auto StoreMnemonic = PPC::STDCX;
13336 switch (AtomicSize) {
13340 LoadMnemonic = PPC::LBARX;
13341 StoreMnemonic = PPC::STBCX;
13342 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13345 LoadMnemonic = PPC::LHARX;
13346 StoreMnemonic = PPC::STHCX;
13347 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13350 LoadMnemonic = PPC::LWARX;
13351 StoreMnemonic = PPC::STWCX;
13354 LoadMnemonic = PPC::LDARX;
13355 StoreMnemonic = PPC::STDCX;
13363 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13374 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13376 F->insert(It, loopMBB);
13378 F->insert(It, loop2MBB);
13379 F->insert(It, exitMBB);
13385 Register TmpReg = (!BinOpcode) ? incr :
13386 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13387 : &PPC::GPRCRegClass);
13412 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13417 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13419 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13420 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13421 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13451 switch(
MI.getOpcode()) {
13455 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13456 &
MI.getMF()->getRegInfo());
13480 case PPC::EXTSB8_32_64:
13481 case PPC::EXTSB8_rec:
13482 case PPC::EXTSB_rec:
13485 case PPC::EXTSH8_32_64:
13486 case PPC::EXTSH8_rec:
13487 case PPC::EXTSH_rec:
13489 case PPC::EXTSWSLI:
13490 case PPC::EXTSWSLI_32_64:
13491 case PPC::EXTSWSLI_32_64_rec:
13492 case PPC::EXTSWSLI_rec:
13493 case PPC::EXTSW_32:
13494 case PPC::EXTSW_32_64:
13495 case PPC::EXTSW_32_64_rec:
13496 case PPC::EXTSW_rec:
13499 case PPC::SRAWI_rec:
13500 case PPC::SRAW_rec:
13510 unsigned OpIdx,
bool IsByte,
13515 bool IsSignExtended =
13518 if (!IsSignExtended) {
13519 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13521 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13523 MI.getOperand(OpIdx).setReg(ValueReg);
13529 unsigned CmpOpcode,
unsigned CmpPred)
const {
13533 assert(!Subtarget.hasPartwordAtomics() &&
13534 "Assumes that part-word atomics are not available");
13542 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13543 if (CmpOpcode == PPC::CMPW)
13551 bool is64bit = Subtarget.isPPC64();
13552 bool isLittleEndian = Subtarget.isLittleEndian();
13553 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13564 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13566 F->insert(It, loopMBB);
13568 F->insert(It, loop2MBB);
13569 F->insert(It, exitMBB);
13575 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13578 Register PtrReg = RegInfo.createVirtualRegister(RC);
13579 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13581 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13582 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13583 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13584 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13585 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13586 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13587 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13588 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13589 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13590 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13593 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13620 if (ptrA != ZeroReg) {
13621 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13622 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13630 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13631 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13634 .
addImm(is8bit ? 28 : 27);
13635 if (!isLittleEndian)
13636 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13638 .
addImm(is8bit ? 24 : 16);
13640 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13645 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13655 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13659 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13664 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13668 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13671 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13678 Register SReg = RegInfo.createVirtualRegister(GPRC);
13679 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13683 unsigned ValueReg = SReg;
13684 unsigned CmpReg = Incr2Reg;
13685 if (CmpOpcode == PPC::CMPW) {
13686 ValueReg = RegInfo.createVirtualRegister(GPRC);
13687 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13690 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13691 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13693 ValueReg = ValueSReg;
13725 .
addImm(is8bit ? 24 : 16)
13746 Register DstReg =
MI.getOperand(0).getReg();
13748 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13753 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13754 "Invalid Pointer Size!");
13803 Register BufReg =
MI.getOperand(1).getReg();
13805 if (Subtarget.is64BitELFABI()) {
13818 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13820 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13823 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13846 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13849 if (Subtarget.isPPC64()) {
13867 TII->get(PPC::PHI), DstReg)
13871 MI.eraseFromParent();
13885 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13886 "Invalid Pointer Size!");
13889 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13892 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13893 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13907 Register BufReg =
MI.getOperand(0).getReg();
13912 if (PVT == MVT::i64) {
13924 if (PVT == MVT::i64) {
13936 if (PVT == MVT::i64) {
13948 if (PVT == MVT::i64) {
13960 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13970 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13973 MI.eraseFromParent();
13989 "Unexpected stack alignment");
13993 unsigned StackProbeSize =
13996 StackProbeSize &= ~(StackAlign - 1);
13997 return StackProbeSize ? StackProbeSize : StackAlign;
14009 const bool isPPC64 = Subtarget.isPPC64();
14041 MF->
insert(MBBIter, TestMBB);
14042 MF->
insert(MBBIter, BlockMBB);
14043 MF->
insert(MBBIter, TailMBB);
14048 Register DstReg =
MI.getOperand(0).getReg();
14049 Register NegSizeReg =
MI.getOperand(1).getReg();
14061 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
14067 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
14068 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
14070 .
addDef(ActualNegSizeReg)
14072 .
add(
MI.getOperand(2))
14073 .
add(
MI.getOperand(3));
14079 .
addReg(ActualNegSizeReg);
14082 int64_t NegProbeSize = -(int64_t)ProbeSize;
14088 .
addImm(NegProbeSize >> 16);
14092 .
addImm(NegProbeSize & 0xFFFF);
14101 .
addReg(ActualNegSizeReg)
14110 .
addReg(ActualNegSizeReg);
14120 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
14147 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
14148 MaxCallFrameSizeReg)
14149 .
add(
MI.getOperand(2))
14150 .
add(
MI.getOperand(3));
14151 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
14153 .
addReg(MaxCallFrameSizeReg);
14159 MBB->addSuccessor(TestMBB);
14162 MI.eraseFromParent();
14164 ++NumDynamicAllocaProbed;
14172static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
14175 case PPC::SELECT_CC_I4:
14176 case PPC::SELECT_CC_I8:
14177 case PPC::SELECT_CC_F4:
14178 case PPC::SELECT_CC_F8:
14179 case PPC::SELECT_CC_F16:
14180 case PPC::SELECT_CC_VRRC:
14181 case PPC::SELECT_CC_VSFRC:
14182 case PPC::SELECT_CC_VSSRC:
14183 case PPC::SELECT_CC_VSRC:
14184 case PPC::SELECT_CC_SPE4:
14185 case PPC::SELECT_CC_SPE:
14188 case PPC::SELECT_I4:
14189 case PPC::SELECT_I8:
14190 case PPC::SELECT_F4:
14191 case PPC::SELECT_F8:
14192 case PPC::SELECT_F16:
14193 case PPC::SELECT_SPE:
14194 case PPC::SELECT_SPE4:
14195 case PPC::SELECT_VRRC:
14196 case PPC::SELECT_VSFRC:
14197 case PPC::SELECT_VSSRC:
14198 case PPC::SELECT_VSRC:
14199 return !CheckOnlyCC;
14215 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
14218 if (Subtarget.hasISEL() &&
14219 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14220 MI.getOpcode() == PPC::SELECT_CC_I8 ||
14221 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
14223 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14224 MI.getOpcode() == PPC::SELECT_CC_I8)
14225 Cond.push_back(
MI.getOperand(4));
14228 Cond.push_back(
MI.getOperand(1));
14231 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
14232 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
14233 MI.eraseFromParent();
14246 F->insert(It, copy0MBB);
14247 F->insert(It, sinkMBB);
14255 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14271 .
addImm(
MI.getOperand(4).getImm())
14272 .
addReg(
MI.getOperand(1).getReg())
14276 .
addReg(
MI.getOperand(1).getReg())
14286 .
addReg(
MI.getOperand(3).getReg())
14288 .
addReg(
MI.getOperand(2).getReg())
14290 MI.eraseFromParent();
14305 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14306 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14307 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14308 F->insert(It, loop1MBB);
14309 F->insert(It, loop2MBB);
14310 F->insert(It, exitMBB);
14345 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14347 unsigned LoadMnemonic = PPC::LDARX;
14348 unsigned StoreMnemonic = PPC::STDCX;
14349 switch (
MI.getOpcode()) {
14352 case PPC::ATOMIC_CMP_SWAP_I8:
14353 LoadMnemonic = PPC::LBARX;
14354 StoreMnemonic = PPC::STBCX;
14355 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14357 case PPC::ATOMIC_CMP_SWAP_I16:
14358 LoadMnemonic = PPC::LHARX;
14359 StoreMnemonic = PPC::STHCX;
14360 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14362 case PPC::ATOMIC_CMP_SWAP_I32:
14363 LoadMnemonic = PPC::LWARX;
14364 StoreMnemonic = PPC::STWCX;
14366 case PPC::ATOMIC_CMP_SWAP_I64:
14367 LoadMnemonic = PPC::LDARX;
14368 StoreMnemonic = PPC::STDCX;
14376 Register oldval =
MI.getOperand(3).getReg();
14377 Register newval =
MI.getOperand(4).getReg();
14391 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14459 bool is64bit = Subtarget.isPPC64();
14461 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14466 Register oldval =
MI.getOperand(3).getReg();
14467 Register newval =
MI.getOperand(4).getReg();
14475 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14480 return RegInfo.createVirtualRegister(RC);
14484 Register Shift1Reg = createVReg(GPRC);
14485 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14486 Register NewVal2Reg = createVReg(GPRC);
14487 Register NewVal3Reg = createVReg(GPRC);
14488 Register OldVal2Reg = createVReg(GPRC);
14489 Register OldVal3Reg = createVReg(GPRC);
14490 Register MaskReg = createVReg(GPRC);
14491 Register Mask2Reg = createVReg(GPRC);
14492 Register Mask3Reg = createVReg(GPRC);
14493 Register Tmp2Reg = createVReg(GPRC);
14494 Register Tmp4Reg = createVReg(GPRC);
14495 Register TmpDestReg = createVReg(GPRC);
14496 Register TmpReg = createVReg(GPRC);
14497 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14498 Register CrReg = createVReg(&PPC::CRRCRegClass);
14502 if (ptrA != ZeroReg) {
14503 Ptr1Reg = createVReg(RC);
14504 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14511 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14512 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14515 .
addImm(is8bit ? 28 : 27);
14516 if (!isLittleEndian)
14517 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14519 .
addImm(is8bit ? 24 : 16);
14521 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14526 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14533 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14536 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14543 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14547 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14550 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14553 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14563 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14584 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14629 switch (
MI.getOpcode()) {
14630 case TargetOpcode::STACKMAP:
14632 case TargetOpcode::PATCHPOINT:
14638 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14642 case PPC::EH_SjLj_SetJmp32:
14643 case PPC::EH_SjLj_SetJmp64:
14646 case PPC::EH_SjLj_LongJmp32:
14647 case PPC::EH_SjLj_LongJmp64:
14650 case PPC::ReadTB: {
14666 F->insert(It, readMBB);
14667 F->insert(It, sinkMBB);
14678 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14686 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14688 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14700 case PPC::ATOMIC_LOAD_ADD_NOWP:
14703 case PPC::ATOMIC_LOAD_ADD:
14706 case PPC::ATOMIC_LOAD_ADD_I64:
14709 case PPC::ATOMIC_LOAD_AND_NOWP:
14712 case PPC::ATOMIC_LOAD_AND:
14715 case PPC::ATOMIC_LOAD_AND_I64:
14718 case PPC::ATOMIC_LOAD_OR_NOWP:
14721 case PPC::ATOMIC_LOAD_OR:
14724 case PPC::ATOMIC_LOAD_OR_I64:
14727 case PPC::ATOMIC_LOAD_XOR_NOWP:
14730 case PPC::ATOMIC_LOAD_XOR:
14733 case PPC::ATOMIC_LOAD_XOR_I64:
14736 case PPC::ATOMIC_LOAD_NAND_NOWP:
14739 case PPC::ATOMIC_LOAD_NAND:
14742 case PPC::ATOMIC_LOAD_NAND_I64:
14745 case PPC::ATOMIC_LOAD_SUB_NOWP:
14748 case PPC::ATOMIC_LOAD_SUB:
14751 case PPC::ATOMIC_LOAD_SUB_I64:
14754 case PPC::ATOMIC_LOAD_MIN_NOWP:
14757 case PPC::ATOMIC_LOAD_MIN:
14760 case PPC::ATOMIC_LOAD_MIN_I64:
14763 case PPC::ATOMIC_LOAD_MAX_NOWP:
14766 case PPC::ATOMIC_LOAD_MAX:
14769 case PPC::ATOMIC_LOAD_MAX_I64:
14772 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14775 case PPC::ATOMIC_LOAD_UMIN:
14778 case PPC::ATOMIC_LOAD_UMIN_I64:
14781 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14784 case PPC::ATOMIC_LOAD_UMAX:
14787 case PPC::ATOMIC_LOAD_UMAX_I64:
14790 case PPC::ATOMIC_SWAP_NOWP:
14793 case PPC::ATOMIC_SWAP:
14794 case PPC::ATOMIC_SWAP_I64:
14797 case PPC::ATOMIC_CMP_SWAP_I32:
14798 case PPC::ATOMIC_CMP_SWAP_I64:
14799 case PPC::ATOMIC_CMP_SWAP_I8:
14800 case PPC::ATOMIC_CMP_SWAP_I16: {
14802 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14803 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14804 (Subtarget.hasPartwordAtomics() &&
14805 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14806 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14814 case PPC::FADDrtz: {
14824 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14839 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14849 case PPC::ANDI_rec_1_EQ_BIT:
14850 case PPC::ANDI_rec_1_GT_BIT:
14851 case PPC::ANDI_rec_1_EQ_BIT8:
14852 case PPC::ANDI_rec_1_GT_BIT8: {
14853 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14854 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14857 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14858 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14861 Register Dest = RegInfo.createVirtualRegister(
14862 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14866 .
addReg(
MI.getOperand(1).getReg())
14869 MI.getOperand(0).getReg())
14870 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14873 case PPC::TCHECK_RET: {
14876 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14879 MI.getOperand(0).getReg())
14883 case PPC::TBEGIN_RET: {
14885 unsigned Imm =
MI.getOperand(1).getImm();
14888 MI.getOperand(0).getReg())
14892 case PPC::SETRNDi: {
14894 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14898 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14900 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14911 unsigned Mode =
MI.getOperand(1).getImm();
14912 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14916 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14921 case PPC::SETRND: {
14929 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14930 if (Subtarget.hasDirectMove()) {
14931 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14935 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14938 if (RC == &PPC::F8RCRegClass) {
14940 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14941 "Unsupported RegClass.");
14943 StoreOp = PPC::STFD;
14947 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14948 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14949 "Unsupported RegClass.");
14982 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14985 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14997 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14999 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
15001 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
15002 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
15007 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
15008 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
15013 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
15014 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
15020 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
15021 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
15032 case PPC::SETFLM: {
15036 Register OldFPSCRReg =
MI.getOperand(0).getReg();
15038 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
15040 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
15043 Register NewFPSCRReg =
MI.getOperand(1).getReg();
15051 case PPC::PROBED_ALLOCA_32:
15052 case PPC::PROBED_ALLOCA_64:
15055 case PPC::SPLIT_QUADWORD: {
15062 .
addUse(Src, {}, PPC::sub_gp8_x1);
15065 .
addUse(Src, {}, PPC::sub_gp8_x0);
15068 case PPC::LQX_PSEUDO:
15069 case PPC::STQX_PSEUDO: {
15075 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
15081 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
15082 :
TII->get(PPC::STQ))
15092 MI.eraseFromParent();
15105 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
15108 return RefinementSteps;
15115 EVT VT =
Op.getValueType();
15118 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
15142PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
15145 EVT VT =
Op.getValueType();
15146 if (VT != MVT::f64 &&
15147 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
15150 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
15154 int Enabled,
int &RefinementSteps,
15155 bool &UseOneConstNR,
15156 bool Reciprocal)
const {
15158 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
15159 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
15160 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15161 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15167 UseOneConstNR = !Subtarget.needsTwoConstNR();
15168 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
15175 int &RefinementSteps)
const {
15177 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
15178 (VT == MVT::f64 && Subtarget.hasFRE()) ||
15179 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15180 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15183 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
15199 switch (Subtarget.getCPUDirective()) {
15226 unsigned Bytes,
int Dist,
15240 if (FS != BFS || FS != (
int)Bytes)
return false;
15245 int64_t Offset1 = 0, Offset2 = 0;
15248 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15258 if (isGA1 && isGA2 && GV1 == GV2)
15259 return Offset1 == (Offset2 + Dist*Bytes);
15266 unsigned Bytes,
int Dist,
15269 EVT VT = LS->getMemoryVT();
15276 switch (
N->getConstantOperandVal(1)) {
15277 default:
return false;
15278 case Intrinsic::ppc_altivec_lvx:
15279 case Intrinsic::ppc_altivec_lvxl:
15280 case Intrinsic::ppc_vsx_lxvw4x:
15281 case Intrinsic::ppc_vsx_lxvw4x_be:
15284 case Intrinsic::ppc_vsx_lxvd2x:
15285 case Intrinsic::ppc_vsx_lxvd2x_be:
15288 case Intrinsic::ppc_altivec_lvebx:
15291 case Intrinsic::ppc_altivec_lvehx:
15294 case Intrinsic::ppc_altivec_lvewx:
15304 switch (
N->getConstantOperandVal(1)) {
15305 default:
return false;
15306 case Intrinsic::ppc_altivec_stvx:
15307 case Intrinsic::ppc_altivec_stvxl:
15308 case Intrinsic::ppc_vsx_stxvw4x:
15311 case Intrinsic::ppc_vsx_stxvd2x:
15314 case Intrinsic::ppc_vsx_stxvw4x_be:
15317 case Intrinsic::ppc_vsx_stxvd2x_be:
15320 case Intrinsic::ppc_altivec_stvebx:
15323 case Intrinsic::ppc_altivec_stvehx:
15326 case Intrinsic::ppc_altivec_stvewx:
15343 SDValue Chain = LD->getChain();
15344 EVT VT = LD->getMemoryVT();
15353 while (!Queue.empty()) {
15354 SDNode *ChainNext = Queue.pop_back_val();
15355 if (!Visited.
insert(ChainNext).second)
15362 if (!Visited.
count(ChainLD->getChain().getNode()))
15363 Queue.push_back(ChainLD->getChain().getNode());
15365 for (
const SDUse &O : ChainNext->
ops())
15366 if (!Visited.
count(O.getNode()))
15367 Queue.push_back(O.getNode());
15369 LoadRoots.
insert(ChainNext);
15380 for (
SDNode *
I : LoadRoots) {
15381 Queue.push_back(
I);
15383 while (!Queue.empty()) {
15384 SDNode *LoadRoot = Queue.pop_back_val();
15385 if (!Visited.
insert(LoadRoot).second)
15397 Queue.push_back(U);
15430 auto Final = Shifted;
15441 DAGCombinerInfo &DCI)
const {
15444 SelectionDAG &DAG = DCI.DAG;
15449 if (!DCI.isAfterLegalizeDAG())
15454 for (
const SDNode *U :
N->users())
15459 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15463 if (OpSize <
Size) {
15481 DAGCombinerInfo &DCI)
const {
15482 SelectionDAG &DAG = DCI.DAG;
15485 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15496 N->getValueType(0) != MVT::i1)
15499 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15500 N->getOperand(0).getValueType() != MVT::i64)
15510 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15521 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15544 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15545 N->getOperand(0).getOpcode() !=
ISD::OR &&
15546 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15556 N->getOperand(1).getOpcode() !=
ISD::AND &&
15557 N->getOperand(1).getOpcode() !=
ISD::OR &&
15558 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15569 SmallPtrSet<SDNode *, 16> Visited;
15571 for (
unsigned i = 0; i < 2; ++i) {
15575 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15587 while (!BinOps.
empty()) {
15595 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15629 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15633 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15634 if (User !=
N && !Visited.
count(User))
15643 if (
User->getOperand(0) == Inputs[i])
15646 if (
User->getOperand(0) == Inputs[i] ||
15647 User->getOperand(1) == Inputs[i])
15653 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15654 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15655 if (User !=
N && !Visited.
count(User))
15664 if (
User->getOperand(0) == PromOps[i])
15667 if (
User->getOperand(0) == PromOps[i] ||
15668 User->getOperand(1) == PromOps[i])
15675 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15684 std::list<HandleSDNode> PromOpHandles;
15685 for (
auto &PromOp : PromOps)
15686 PromOpHandles.emplace_back(PromOp);
15693 while (!PromOpHandles.empty()) {
15694 SDValue PromOp = PromOpHandles.back().getValue();
15695 PromOpHandles.pop_back();
15704 PromOpHandles.emplace_front(PromOp);
15718 default:
C = 0;
break;
15731 PromOpHandles.emplace_front(PromOp);
15738 for (
unsigned i = 0; i < 2; ++i)
15748 return N->getOperand(0);
15756 DAGCombinerInfo &DCI)
const {
15757 SelectionDAG &DAG = DCI.DAG;
15774 if (
N->getValueType(0) != MVT::i32 &&
15775 N->getValueType(0) != MVT::i64)
15778 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15779 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15782 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15783 N->getOperand(0).getOpcode() !=
ISD::OR &&
15784 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15791 SmallPtrSet<SDNode *, 16> Visited;
15795 while (!BinOps.
empty()) {
15803 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15829 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15834 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15839 if (User !=
N && !Visited.
count(User))
15845 if (
User->getOperand(0) == Inputs[i])
15846 SelectTruncOp[0].
insert(std::make_pair(User,
15847 User->getOperand(0).getValueType()));
15849 if (
User->getOperand(0) == Inputs[i])
15850 SelectTruncOp[0].
insert(std::make_pair(User,
15851 User->getOperand(0).getValueType()));
15852 if (
User->getOperand(1) == Inputs[i])
15853 SelectTruncOp[1].
insert(std::make_pair(User,
15854 User->getOperand(1).getValueType()));
15859 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15861 if (User !=
N && !Visited.
count(User))
15867 if (
User->getOperand(0) == PromOps[i])
15868 SelectTruncOp[0].
insert(std::make_pair(User,
15869 User->getOperand(0).getValueType()));
15871 if (
User->getOperand(0) == PromOps[i])
15872 SelectTruncOp[0].
insert(std::make_pair(User,
15873 User->getOperand(0).getValueType()));
15874 if (
User->getOperand(1) == PromOps[i])
15875 SelectTruncOp[1].
insert(std::make_pair(User,
15876 User->getOperand(1).getValueType()));
15881 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15882 bool ReallyNeedsExt =
false;
15886 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15891 Inputs[i].getOperand(0).getValueSizeInBits();
15892 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15897 OpBits-PromBits))) ||
15900 (OpBits-(PromBits-1)))) {
15901 ReallyNeedsExt =
true;
15909 std::list<HandleSDNode> PromOpHandles;
15910 for (
auto &PromOp : PromOps)
15911 PromOpHandles.emplace_back(PromOp);
15915 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15922 SDValue InSrc = Inputs[i].getOperand(0);
15940 while (!PromOpHandles.empty()) {
15942 PromOpHandles.pop_back();
15946 default:
C = 0;
break;
15959 PromOpHandles.emplace_front(PromOp);
15969 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15971 PromOpHandles.emplace_front(PromOp);
15979 for (
unsigned i = 0; i < 2; ++i) {
15997 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15998 if (SI0 != SelectTruncOp[0].
end())
16000 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
16001 if (SI1 != SelectTruncOp[1].
end())
16010 if (!ReallyNeedsExt)
16011 return N->getOperand(0);
16018 N->getValueSizeInBits(0), PromBits),
16019 dl,
N->getValueType(0)));
16022 "Invalid extension type");
16025 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
16035 auto isValidForConvert = [IsPPC64](
SDValue &Operand) {
16044 const APInt &Val =
C->getAPIntValue();
16050 if (IsPPC64 && Val.
ult(1ULL << 16))
16064 if (LoadNode->isVolatile())
16085 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
16095 "CC mus be ISD::SETNE or ISD::SETEQ");
16097 auto getV16i8Load = [&](
const SDValue &Operand) {
16115 LoadNode->getBasePtr(), NewMMO);
16156 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
16157 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
16160 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
16163 IntrID, CRSel, LHSVec, RHSVec);
16166 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
16184 auto IsAndWithOne = [](
SDValue &V) {
16195 auto IsCompareWithZero = [](
SDValue &V) {
16202 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
16203 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
16220 auto MakeXor1 = [&](
SDValue V) {
16221 EVT VT = V.getValueType();
16228 return MakeXor1(
LHS);
16231 return MakeXor1(
RHS);
16248 DAGCombinerInfo &DCI)
const {
16249 if (Subtarget.isISA3_1())
16252 EVT VT =
N->getValueType(0);
16253 if (VT != MVT::i32 && (VT != MVT::i64 || !Subtarget.isPPC64()))
16269 SelectionDAG &DAG = DCI.DAG;
16271 EVT XVT =
X.getValueType();
16275 MVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16288 Addc, Addc, Carry);
16291 if (OpVT == MVT::i64 && VT == MVT::i32)
16298 DAGCombinerInfo &DCI)
const {
16300 "Should be called with a SETCC node");
16322 SelectionDAG &DAG = DCI.DAG;
16323 EVT VT =
N->getValueType(0);
16324 EVT OpVT =
LHS.getValueType();
16342 if (Subtarget.hasAltivec() &&
16347 return DAGCombineTruncBoolExt(
N, DCI);
16354 Op.getValueType() == MVT::f64;
16366combineElementTruncationToVectorTruncation(
SDNode *
N,
16367 DAGCombinerInfo &DCI)
const {
16369 "Should be called with a BUILD_VECTOR node");
16371 SelectionDAG &DAG = DCI.DAG;
16374 SDValue FirstInput =
N->getOperand(0);
16376 "The input operand must be an fp-to-int conversion.");
16381 if (FirstConversion == PPCISD::FCTIDZ ||
16382 FirstConversion == PPCISD::FCTIDUZ ||
16383 FirstConversion == PPCISD::FCTIWZ ||
16384 FirstConversion == PPCISD::FCTIWUZ) {
16385 bool IsSplat =
true;
16386 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16387 FirstConversion == PPCISD::FCTIWUZ;
16390 EVT TargetVT =
N->getValueType(0);
16391 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16392 SDValue NextOp =
N->getOperand(i);
16393 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16396 if (NextConversion != FirstConversion)
16404 if (
N->getOperand(i) != FirstInput)
16415 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16416 SDValue In =
N->getOperand(i).getOperand(0);
16426 Ops.push_back(Trunc);
16429 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16433 if (FirstConversion == PPCISD::FCTIDZ ||
16434 FirstConversion == PPCISD::FCTIWZ)
16439 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16441 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16459 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16463 if (FullVal == BasePattern)
16464 return std::make_tuple(Uim,
uint8_t{0});
16467 if (FullVal ==
APInt(128, 1))
16468 return std::make_tuple(Uim,
uint8_t{127});
16470 return std::nullopt;
16490 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16494 EVT VT =
Op.getValueType();
16495 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16509 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16519 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16523 uint64_t ElemValue =
C->getZExtValue();
16527 ElemValue &= ((1ULL << ElemBits) - 1);
16531 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16534 APInt ElemAPInt(128, ElemValue);
16535 ElemAPInt <<= BitPos;
16538 FullVal |= ElemAPInt;
16545 const auto &[Uim, ShiftAmount] = *UIMOpt;
16549 if (ShiftAmount == 0) {
16554 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16555 LxvkqInstr.
dump());
16559 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16571 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16574 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16590 "Should be called with a BUILD_VECTOR node");
16595 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16598 bool InputsAreConsecutiveLoads =
true;
16599 bool InputsAreReverseConsecutive =
true;
16600 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16601 SDValue FirstInput =
N->getOperand(0);
16602 bool IsRoundOfExtLoad =
false;
16612 N->getNumOperands() == 1)
16615 if (!IsRoundOfExtLoad)
16620 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16622 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16625 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16631 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16642 InputsAreConsecutiveLoads =
false;
16644 InputsAreReverseConsecutive =
false;
16647 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16652 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16653 "The loads cannot be both consecutive and reverse consecutive.");
16657 if (InputsAreConsecutiveLoads) {
16658 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16662 ReturnSDVal = WideLoad;
16663 }
else if (InputsAreReverseConsecutive) {
16665 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16670 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16678 for (
auto *LD : InputLoads)
16680 return ReturnSDVal;
16691 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16697 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16699 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16701 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16702 CorrectElems = CorrectElems >> 8;
16703 Elems = Elems >> 8;
16710 EVT VT =
N->getValueType(0);
16714 Input.getValueType().getVectorElementType(),
16748 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16774 Elems = Elems << 8;
16783 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16784 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16791 int TgtElemArrayIdx;
16792 int InputSize =
Input.getValueType().getScalarSizeInBits();
16793 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16794 if (InputSize + OutputSize == 40)
16795 TgtElemArrayIdx = 0;
16796 else if (InputSize + OutputSize == 72)
16797 TgtElemArrayIdx = 1;
16798 else if (InputSize + OutputSize == 48)
16799 TgtElemArrayIdx = 2;
16800 else if (InputSize + OutputSize == 80)
16801 TgtElemArrayIdx = 3;
16802 else if (InputSize + OutputSize == 96)
16803 TgtElemArrayIdx = 4;
16807 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16809 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16810 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16811 if (Elems != CorrectElems) {
16827 if (
N->getValueType(0) != MVT::v1i128)
16830 SDValue Operand =
N->getOperand(0);
16837 EVT MemoryType = LD->getMemoryVT();
16841 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16842 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16845 if (!ValidLDType ||
16851 LD->getChain(), LD->getBasePtr(),
16855 DAG.
getVTList(MVT::v1i128, MVT::Other),
16856 LoadOps, MemoryType, LD->getMemOperand());
16860 DAGCombinerInfo &DCI)
const {
16862 "Should be called with a BUILD_VECTOR node");
16864 SelectionDAG &DAG = DCI.DAG;
16867 if (!Subtarget.hasVSX())
16874 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16875 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16890 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16899 if (Subtarget.isISA3_1()) {
16905 if (
N->getValueType(0) != MVT::v2f64)
16916 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16927 if (!Ext1Op || !Ext2Op)
16936 if (FirstElem == 0 && SecondElem == 1)
16937 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16938 else if (FirstElem == 2 && SecondElem == 3)
16939 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16945 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16946 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16951 DAGCombinerInfo &DCI)
const {
16954 "Need an int -> FP conversion node here");
16959 SelectionDAG &DAG = DCI.DAG;
16965 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16967 if (!
Op.getOperand(0).getValueType().isSimple())
16969 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16970 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16973 SDValue FirstOperand(
Op.getOperand(0));
16974 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16975 (FirstOperand.getValueType() == MVT::i8 ||
16976 FirstOperand.getValueType() == MVT::i16);
16977 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16979 bool DstDouble =
Op.getValueType() == MVT::f64;
16980 unsigned ConvOp =
Signed ?
16981 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16982 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16987 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16990 Ops, MVT::i8, LDN->getMemOperand());
16995 SDValue ExtOps[] = { Ld, WidthConst };
16997 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16999 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
17007 if (
Op.getOperand(0).getValueType() == MVT::i32)
17011 "UINT_TO_FP is supported only with FPCVT");
17015 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
17020 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
17027 Subtarget.hasFPCVT()) ||
17029 SDValue Src =
Op.getOperand(0).getOperand(0);
17030 if (Src.getValueType() == MVT::f32) {
17032 DCI.AddToWorklist(Src.getNode());
17033 }
else if (Src.getValueType() != MVT::f64) {
17045 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
17048 DCI.AddToWorklist(
FP.getNode());
17072 switch (
N->getOpcode()) {
17077 Chain = LD->getChain();
17078 Base = LD->getBasePtr();
17079 MMO = LD->getMemOperand();
17098 MVT VecTy =
N->getValueType(0).getSimpleVT();
17106 Chain =
Load.getValue(1);
17108 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain,
Load);
17112 if (VecTy != MVT::v2f64) {
17117 N,
Swap.getValue(1));
17139 switch (
N->getOpcode()) {
17144 Chain = ST->getChain();
17145 Base = ST->getBasePtr();
17146 MMO = ST->getMemOperand();
17166 SDValue Src =
N->getOperand(SrcOpnd);
17167 MVT VecTy = Src.getValueType().getSimpleVT();
17170 if (VecTy != MVT::v2f64) {
17176 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
17178 Chain =
Swap.getValue(1);
17182 StoreOps, VecTy, MMO);
17189 DAGCombinerInfo &DCI)
const {
17192 unsigned Opcode =
N->getOperand(1).getOpcode();
17194 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
17198 &&
"Not a FP_TO_INT Instruction!");
17201 EVT Op1VT =
N->getOperand(1).getValueType();
17204 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
17208 bool ValidTypeForStoreFltAsInt =
17209 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
17210 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
17213 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
17216 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
17224 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
17239 bool PrevElemFromFirstVec = Mask[0] < NumElts;
17240 for (
int i = 1, e = Mask.size(); i < e; i++) {
17241 if (PrevElemFromFirstVec && Mask[i] < NumElts)
17243 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
17245 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17256 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17257 FirstOp =
Op.getOperand(i);
17263 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17264 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17274 Op =
Op.getOperand(0);
17290 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17291 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
17293 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17295 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17296 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17297 int Idx = ShuffV[
I];
17298 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17299 ShuffV[
I] += LHSEltFixup;
17300 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17301 ShuffV[
I] += RHSEltFixup;
17312 SDLoc dl(OrigSToV);
17315 "Expecting a SCALAR_TO_VECTOR here");
17328 "Cannot produce a permuted scalar_to_vector for one element vector");
17330 unsigned ResultInElt = NumElts / 2;
17336 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17341 int HalfVec,
int LHSLastElementDefined,
17342 int RHSLastElementDefined) {
17343 for (
int Index : ShuffV) {
17347 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17348 (Index > LHSLastElementDefined))
17351 if ((RHSLastElementDefined >= 0) &&
17352 (Index > HalfVec + RHSLastElementDefined))
17359 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17360 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17376 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17377 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17380 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17381 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17382 return SToVPermuted;
17402 int NumElts =
LHS.getValueType().getVectorNumElements();
17405 bool IsLittleEndian = Subtarget.isLittleEndian();
17412 if (!Subtarget.hasDirectMove())
17432 SmallVector<int, 16> ShuffV(Mask);
17435 if (SToVLHS || SToVRHS) {
17438 int ShuffleNumElts = ShuffV.
size();
17439 int HalfVec = ShuffleNumElts / 2;
17445 unsigned LHSNumValidElts = HalfVec;
17446 unsigned RHSNumValidElts = HalfVec;
17451 int LHSFirstElt = 0;
17452 int RHSFirstElt = ShuffleNumElts;
17453 int LHSLastElt = -1;
17454 int RHSLastElt = -1;
17462 int LHSScalarSize = 0;
17463 int RHSScalarSize = 0;
17466 if (!IsLittleEndian && LHSScalarSize >= 64)
17471 if (!IsLittleEndian && RHSScalarSize >= 64)
17474 if (LHSScalarSize != 0)
17476 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17477 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17478 if (RHSScalarSize != 0)
17480 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17481 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17492 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17493 LHSNumValidElts, RHSNumValidElts, Subtarget);
17519 if (IsLittleEndian) {
17522 if (Mask[0] < NumElts)
17523 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17527 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17532 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17536 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17541 if (Mask[0] < NumElts)
17542 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17546 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17551 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17555 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17565 if (IsLittleEndian)
17574 DAGCombinerInfo &DCI)
const {
17576 "Not a reverse memop pattern!");
17578 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17581 auto I =
Mask.rbegin();
17582 auto E =
Mask.rend();
17584 for (;
I !=
E; ++
I) {
17592 SelectionDAG &DAG = DCI.DAG;
17595 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17601 if (!Subtarget.hasP9Vector())
17604 if(!IsElementReverse(SVN))
17611 for (SDUse &Use : LSBase->
uses())
17612 if (
Use.getResNo() == 0 &&
17619 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17634 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17643 if (IntrinsicID == Intrinsic::ppc_stdcx)
17645 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17647 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17649 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17658 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17662 if (
LHS->getOpcode() == PPCISD::ADDE &&
17673 if (
N->getOpcode() == PPCISD::SUBE) {
17679 if (
LHS ==
RHS &&
LHS.getOpcode() == PPCISD::ADDC) {
17682 if (AddcLHS.
getOpcode() == PPCISD::ADDE &&
17704 SDValue CmpLHS =
N->getOperand(0);
17705 SDValue CmpRHS =
N->getOperand(1);
17706 SDValue TrueVal =
N->getOperand(2);
17707 SDValue FalseVal =
N->getOperand(3);
17721 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17724 SDValue ShiftVal = FalseVal.getOperand(0);
17725 SDValue ShiftAmt = FalseVal.getOperand(1);
17729 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17756 if (CtlzArg != CmpLHS)
17764 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17811 auto isZeroOrOne = [=](
SDValue &V) {
17813 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17818 if (!isZeroOrOne(NonNullConstant))
17828 EVT VType =
N->getValueType(0);
17832 return NewNonNullConstant;
17851 EVT XorVT =
N->getValueType(0);
17852 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17860 if (!XorConst || !XorConst->
isOne()) {
17862 if (!XorConst || !XorConst->
isOne())
17869 if (!
LHS.hasOneUse())
17877 SelectNode =
LHS.getOperand(0);
17891 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17901 if (!ConstOp1 || !ConstOp2)
17905 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17914 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17916 bool ConstOp1IsOne = ConstOp1->
isOne();
17919 {SelectNode.getOperand(0),
17920 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17921 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17922 SelectNode.getOperand(3)}),
17930 switch (
N->getOpcode()) {
17933 return combineADD(
N, DCI);
17965 return combineSHL(
N, DCI);
17967 return combineSRA(
N, DCI);
17969 return combineSRL(
N, DCI);
17971 return combineMUL(
N, DCI);
17973 case PPCISD::FNMSUB:
17974 return combineFMALike(
N, DCI);
17977 return N->getOperand(0);
17981 return N->getOperand(0);
17987 return N->getOperand(0);
17998 N->getValueType(0) == MVT::i64 && N0.
getValueType() == MVT::i32 &&
18006 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
18015 return DAGCombineExtBoolTrunc(
N, DCI);
18017 return combineTRUNCATE(
N, DCI);
18019 if (
SDValue CSCC = combineSetCC(
N, DCI))
18025 return DAGCombineTruncBoolExt(
N, DCI);
18028 return combineFPToIntToFP(
N, DCI);
18037 EVT Op1VT =
N->getOperand(1).getValueType();
18038 unsigned Opcode =
N->getOperand(1).getOpcode();
18042 SDValue Val = combineStoreFPToInt(
N, DCI);
18056 N->getOperand(1).getNode()->hasOneUse() &&
18057 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
18058 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
18066 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
18073 if (Op1VT.
bitsGT(mVT)) {
18078 if (Op1VT == MVT::i64)
18083 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
18103 ST->getBasePtr(), ST->getOffset(), MemVT,
18104 ST->getMemOperand(), ST->getAddressingMode(),
18108 return ST->isUnindexed()
18117 if (Subtarget.needsSwapsForVSXMemOps() &&
18118 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
18119 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
18126 EVT VT = LD->getValueType(0);
18132 if (Subtarget.needsSwapsForVSXMemOps() &&
18133 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
18134 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
18145 auto ReplaceTwoFloatLoad = [&]() {
18146 if (VT != MVT::i64)
18161 if (!LD->hasNUsesOfValue(2, 0))
18164 auto UI = LD->user_begin();
18165 while (UI.getUse().getResNo() != 0) ++UI;
18167 while (UI.getUse().getResNo() != 0) ++UI;
18168 SDNode *RightShift = *UI;
18176 if (RightShift->getOpcode() !=
ISD::SRL ||
18178 RightShift->getConstantOperandVal(1) != 32 ||
18179 !RightShift->hasOneUse())
18182 SDNode *Trunc2 = *RightShift->user_begin();
18192 Bitcast->getValueType(0) != MVT::f32)
18198 if (Subtarget.isLittleEndian())
18204 SDValue BasePtr = LD->getBasePtr();
18205 if (LD->isIndexed()) {
18207 "Non-pre-inc AM on PPC?");
18215 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
18216 LD->getPointerInfo(), LD->getAlign(),
18217 MMOFlags, LD->getAAInfo());
18223 LD->getPointerInfo().getWithOffset(4),
18226 if (LD->isIndexed()) {
18240 if (ReplaceTwoFloatLoad())
18243 EVT MemVT = LD->getMemoryVT();
18246 if (LD->isUnindexed() && VT.
isVector() &&
18249 !Subtarget.hasP8Vector() &&
18250 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
18251 VT == MVT::v4f32))) &&
18252 LD->getAlign() < ABIAlignment) {
18254 SDValue Chain = LD->getChain();
18255 SDValue Ptr = LD->getBasePtr();
18256 bool isLittleEndian = Subtarget.isLittleEndian();
18283 MVT PermCntlTy, PermTy, LDTy;
18284 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18285 : Intrinsic::ppc_altivec_lvsl;
18286 IntrLD = Intrinsic::ppc_altivec_lvx;
18287 IntrPerm = Intrinsic::ppc_altivec_vperm;
18288 PermCntlTy = MVT::v16i8;
18289 PermTy = MVT::v4i32;
18308 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18312 BaseLoadOps, LDTy, BaseMMO);
18321 int IncValue = IncOffset;
18338 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18342 ExtraLoadOps, LDTy, ExtraMMO);
18353 if (isLittleEndian)
18355 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18358 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18361 Perm = Subtarget.hasAltivec()
18376 bool isLittleEndian = Subtarget.isLittleEndian();
18377 unsigned IID =
N->getConstantOperandVal(0);
18378 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18379 : Intrinsic::ppc_altivec_lvsl);
18380 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18387 .zext(
Add.getScalarValueSizeInBits()))) {
18388 SDNode *BasePtr =
Add->getOperand(0).getNode();
18389 for (
SDNode *U : BasePtr->users()) {
18391 U->getConstantOperandVal(0) == IID) {
18402 SDNode *BasePtr =
Add->getOperand(0).getNode();
18403 for (
SDNode *U : BasePtr->users()) {
18406 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18412 V->getConstantOperandVal(0) == IID) {
18424 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18425 IID == Intrinsic::ppc_altivec_vmaxsh ||
18426 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18429 if ((
V1.getSimpleValueType() == MVT::v4i32 ||
18430 V1.getSimpleValueType() == MVT::v8i16 ||
18431 V1.getSimpleValueType() == MVT::v16i8) &&
18436 V1.getOperand(1) == V2) {
18457 switch (
N->getConstantOperandVal(1)) {
18460 case Intrinsic::ppc_altivec_vsum4sbs:
18461 case Intrinsic::ppc_altivec_vsum4shs:
18462 case Intrinsic::ppc_altivec_vsum4ubs: {
18469 APInt APSplatBits, APSplatUndef;
18470 unsigned SplatBitSize;
18473 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18474 !Subtarget.isLittleEndian());
18476 if (BVNIsConstantSplat && APSplatBits == 0)
18481 case Intrinsic::ppc_vsx_lxvw4x:
18482 case Intrinsic::ppc_vsx_lxvd2x:
18485 if (Subtarget.needsSwapsForVSXMemOps())
18493 if (Subtarget.needsSwapsForVSXMemOps()) {
18494 switch (
N->getConstantOperandVal(1)) {
18497 case Intrinsic::ppc_vsx_stxvw4x:
18498 case Intrinsic::ppc_vsx_stxvd2x:
18507 bool Is64BitBswapOn64BitTgt =
18508 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18510 N->getOperand(0).hasOneUse();
18511 if (IsSingleUseNormalLd &&
18512 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18513 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18524 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18525 MVT::i64 : MVT::i32, MVT::Other),
18526 Ops, LD->getMemoryVT(), LD->getMemOperand());
18530 if (
N->getValueType(0) == MVT::i16)
18547 !IsSingleUseNormalLd)
18552 if (!LD->isSimple())
18554 SDValue BasePtr = LD->getBasePtr();
18556 LD->getPointerInfo(), LD->getAlign());
18561 LD->getMemOperand(), 4, 4);
18565 if (Subtarget.isLittleEndian())
18571 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18580 if (!
N->getOperand(0).hasOneUse() &&
18581 !
N->getOperand(1).hasOneUse() &&
18582 !
N->getOperand(2).hasOneUse()) {
18585 SDNode *VCMPrecNode =
nullptr;
18587 SDNode *LHSN =
N->getOperand(0).getNode();
18589 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18593 VCMPrecNode =
User;
18605 SDNode *FlagUser =
nullptr;
18607 FlagUser ==
nullptr; ++UI) {
18608 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18621 return SDValue(VCMPrecNode, 0);
18632 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18643 auto RHSAPInt = RHS->getAsAPIntVal();
18644 if (!RHSAPInt.isIntN(64))
18647 unsigned Val = RHSAPInt.getZExtValue();
18648 auto isImpossibleCompare = [&]() {
18651 if (Val != 0 && Val != 1) {
18653 return N->getOperand(0);
18656 N->getOperand(0),
N->getOperand(4));
18661 unsigned StoreWidth = 0;
18664 if (
SDValue Impossible = isImpossibleCompare())
18676 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18680 PPCISD::STORE_COND, dl,
18682 MemNode->getMemoryVT(), MemNode->getMemOperand());
18686 if (
N->getOperand(0) == LHS.getValue(1))
18697 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18699 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18705 assert(isDot &&
"Can't compare against a vector result!");
18707 if (
SDValue Impossible = isImpossibleCompare())
18710 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18717 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18722 switch (LHS.getConstantOperandVal(1)) {
18738 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18741 N->getOperand(4), CompNode.
getValue(1));
18746 return DAGCombineBuildVector(
N, DCI);
18753 return DAGCombineBitcast(
N, DCI);
18764 EVT VT =
N->getValueType(0);
18765 if (VT == MVT::i64 && !Subtarget.isPPC64())
18767 if ((VT != MVT::i32 && VT != MVT::i64) ||
18775 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18795 const APInt &DemandedElts,
18797 unsigned Depth)
const {
18799 switch (
Op.getOpcode()) {
18801 case PPCISD::LBRX: {
18804 Known.Zero = 0xFFFF0000;
18807 case PPCISD::ADDE: {
18808 if (
Op.getResNo() == 0) {
18813 Known.Zero = ~1ULL;
18818 switch (
Op.getConstantOperandVal(0)) {
18820 case Intrinsic::ppc_altivec_vcmpbfp_p:
18821 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18822 case Intrinsic::ppc_altivec_vcmpequb_p:
18823 case Intrinsic::ppc_altivec_vcmpequh_p:
18824 case Intrinsic::ppc_altivec_vcmpequw_p:
18825 case Intrinsic::ppc_altivec_vcmpequd_p:
18826 case Intrinsic::ppc_altivec_vcmpequq_p:
18827 case Intrinsic::ppc_altivec_vcmpgefp_p:
18828 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18829 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18830 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18831 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18832 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18833 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18834 case Intrinsic::ppc_altivec_vcmpgtub_p:
18835 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18836 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18837 case Intrinsic::ppc_altivec_vcmpgtud_p:
18838 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18845 switch (
Op.getConstantOperandVal(1)) {
18848 case Intrinsic::ppc_load2r:
18850 Known.Zero = 0xFFFF0000;
18859 switch (Subtarget.getCPUDirective()) {
18881 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18889 uint64_t LoopSize = 0;
18890 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18892 LoopSize +=
TII->getInstSizeInBytes(J);
18897 if (LoopSize > 16 && LoopSize <= 32)
18911 if (Constraint.
size() == 1) {
18912 switch (Constraint[0]) {
18930 }
else if (Constraint ==
"wc") {
18932 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18933 Constraint ==
"wf" || Constraint ==
"ws" ||
18934 Constraint ==
"wi" || Constraint ==
"ww") {
18947 Value *CallOperandVal =
info.CallOperandVal;
18950 if (!CallOperandVal)
18957 else if ((
StringRef(constraint) ==
"wa" ||
18969 switch (*constraint) {
18999std::pair<unsigned, const TargetRegisterClass *>
19003 if (Constraint.
size() == 1) {
19005 switch (Constraint[0]) {
19007 if (VT == MVT::i64 && Subtarget.isPPC64())
19008 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
19009 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
19011 if (VT == MVT::i64 && Subtarget.isPPC64())
19012 return std::make_pair(0U, &PPC::G8RCRegClass);
19013 return std::make_pair(0U, &PPC::GPRCRegClass);
19019 if (Subtarget.hasSPE()) {
19020 if (VT == MVT::f32 || VT == MVT::i32)
19021 return std::make_pair(0U, &PPC::GPRCRegClass);
19022 if (VT == MVT::f64 || VT == MVT::i64)
19023 return std::make_pair(0U, &PPC::SPERCRegClass);
19025 if (VT == MVT::f32 || VT == MVT::i32)
19026 return std::make_pair(0U, &PPC::F4RCRegClass);
19027 if (VT == MVT::f64 || VT == MVT::i64)
19028 return std::make_pair(0U, &PPC::F8RCRegClass);
19032 if (Subtarget.hasAltivec() && VT.
isVector())
19033 return std::make_pair(0U, &PPC::VRRCRegClass);
19034 else if (Subtarget.hasVSX())
19036 return std::make_pair(0U, &PPC::VFRCRegClass);
19039 return std::make_pair(0U, &PPC::CRRCRegClass);
19041 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
19043 return std::make_pair(0U, &PPC::CRBITRCRegClass);
19044 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
19045 Constraint ==
"wf" || Constraint ==
"wi") &&
19046 Subtarget.hasVSX()) {
19050 return std::make_pair(0U, &PPC::VSRCRegClass);
19051 if (VT == MVT::f32 && Subtarget.hasP8Vector())
19052 return std::make_pair(0U, &PPC::VSSRCRegClass);
19053 return std::make_pair(0U, &PPC::VSFRCRegClass);
19054 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
19055 if (VT == MVT::f32 && Subtarget.hasP8Vector())
19056 return std::make_pair(0U, &PPC::VSSRCRegClass);
19058 return std::make_pair(0U, &PPC::VSFRCRegClass);
19059 }
else if (Constraint ==
"lr") {
19060 if (VT == MVT::i64)
19061 return std::make_pair(0U, &PPC::LR8RCRegClass);
19063 return std::make_pair(0U, &PPC::LRRCRegClass);
19068 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
19072 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
19073 int VSNum = atoi(Constraint.
data() + 3);
19074 assert(VSNum >= 0 && VSNum <= 63 &&
19075 "Attempted to access a vsr out of range");
19077 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
19078 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
19083 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
19084 int RegNum = atoi(Constraint.
data() + 2);
19085 if (RegNum > 31 || RegNum < 0)
19087 if (VT == MVT::f32 || VT == MVT::i32)
19088 return Subtarget.hasSPE()
19089 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
19090 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
19091 if (VT == MVT::f64 || VT == MVT::i64)
19092 return Subtarget.hasSPE()
19093 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
19094 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
19098 std::pair<unsigned, const TargetRegisterClass *> R =
19107 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
19108 PPC::GPRCRegClass.contains(R.first))
19109 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
19110 PPC::sub_32, &PPC::G8RCRegClass),
19111 &PPC::G8RCRegClass);
19114 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
19115 R.first = PPC::CR0;
19116 R.second = &PPC::CRRCRegClass;
19120 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
19121 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
19122 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
19123 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
19124 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
19125 "default AIX AltiVec ABI and cannot be used\n";
19135 std::vector<SDValue> &
Ops,
19140 if (Constraint.
size() > 1)
19143 char Letter = Constraint[0];
19158 EVT TCVT = MVT::i64;
19199 if (Result.getNode()) {
19200 Ops.push_back(Result);
19211 if (
I.getNumOperands() <= 1)
19215 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
19216 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
19217 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
19220 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
19236 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
19248 switch (AM.
Scale) {
19276 unsigned Depth =
Op.getConstantOperandVal(0);
19300 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19308 unsigned Depth =
Op.getConstantOperandVal(0);
19315 bool isPPC64 = PtrVT == MVT::i64;
19321 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19323 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19329 FrameAddr, MachinePointerInfo());
19333#define GET_REGISTER_MATCHER
19334#include "PPCGenAsmMatcher.inc"
19338 bool IsPPC64 = Subtarget.isPPC64();
19350 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19356 Reg = Reg.id() - PPC::R0 + PPC::X0;
19363 if (Subtarget.is32BitELFABI())
19368 if (Subtarget.isAIXABI())
19382 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19398 case Intrinsic::ppc_atomicrmw_xchg_i128:
19399 case Intrinsic::ppc_atomicrmw_add_i128:
19400 case Intrinsic::ppc_atomicrmw_sub_i128:
19401 case Intrinsic::ppc_atomicrmw_nand_i128:
19402 case Intrinsic::ppc_atomicrmw_and_i128:
19403 case Intrinsic::ppc_atomicrmw_or_i128:
19404 case Intrinsic::ppc_atomicrmw_xor_i128:
19405 case Intrinsic::ppc_cmpxchg_i128:
19407 Info.memVT = MVT::i128;
19408 Info.ptrVal =
I.getArgOperand(0);
19410 Info.align =
Align(16);
19415 case Intrinsic::ppc_atomic_load_i128:
19417 Info.memVT = MVT::i128;
19418 Info.ptrVal =
I.getArgOperand(0);
19420 Info.align =
Align(16);
19424 case Intrinsic::ppc_atomic_store_i128:
19426 Info.memVT = MVT::i128;
19427 Info.ptrVal =
I.getArgOperand(2);
19429 Info.align =
Align(16);
19433 case Intrinsic::ppc_altivec_lvx:
19434 case Intrinsic::ppc_altivec_lvxl:
19435 case Intrinsic::ppc_altivec_lvebx:
19436 case Intrinsic::ppc_altivec_lvehx:
19437 case Intrinsic::ppc_altivec_lvewx:
19438 case Intrinsic::ppc_vsx_lxvd2x:
19439 case Intrinsic::ppc_vsx_lxvw4x:
19440 case Intrinsic::ppc_vsx_lxvd2x_be:
19441 case Intrinsic::ppc_vsx_lxvw4x_be:
19442 case Intrinsic::ppc_vsx_lxvl:
19443 case Intrinsic::ppc_vsx_lxvll: {
19446 case Intrinsic::ppc_altivec_lvebx:
19449 case Intrinsic::ppc_altivec_lvehx:
19452 case Intrinsic::ppc_altivec_lvewx:
19455 case Intrinsic::ppc_vsx_lxvd2x:
19456 case Intrinsic::ppc_vsx_lxvd2x_be:
19466 Info.ptrVal =
I.getArgOperand(0);
19469 Info.align =
Align(1);
19474 case Intrinsic::ppc_altivec_stvx:
19475 case Intrinsic::ppc_altivec_stvxl:
19476 case Intrinsic::ppc_altivec_stvebx:
19477 case Intrinsic::ppc_altivec_stvehx:
19478 case Intrinsic::ppc_altivec_stvewx:
19479 case Intrinsic::ppc_vsx_stxvd2x:
19480 case Intrinsic::ppc_vsx_stxvw4x:
19481 case Intrinsic::ppc_vsx_stxvd2x_be:
19482 case Intrinsic::ppc_vsx_stxvw4x_be:
19483 case Intrinsic::ppc_vsx_stxvl:
19484 case Intrinsic::ppc_vsx_stxvll: {
19487 case Intrinsic::ppc_altivec_stvebx:
19490 case Intrinsic::ppc_altivec_stvehx:
19493 case Intrinsic::ppc_altivec_stvewx:
19496 case Intrinsic::ppc_vsx_stxvd2x:
19497 case Intrinsic::ppc_vsx_stxvd2x_be:
19507 Info.ptrVal =
I.getArgOperand(1);
19510 Info.align =
Align(1);
19515 case Intrinsic::ppc_stdcx:
19516 case Intrinsic::ppc_stwcx:
19517 case Intrinsic::ppc_sthcx:
19518 case Intrinsic::ppc_stbcx: {
19520 auto Alignment =
Align(8);
19522 case Intrinsic::ppc_stdcx:
19525 case Intrinsic::ppc_stwcx:
19527 Alignment =
Align(4);
19529 case Intrinsic::ppc_sthcx:
19531 Alignment =
Align(2);
19533 case Intrinsic::ppc_stbcx:
19535 Alignment =
Align(1);
19540 Info.ptrVal =
I.getArgOperand(0);
19542 Info.align = Alignment;
19560 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19561 if (
Op.isMemset() && Subtarget.hasVSX()) {
19562 uint64_t TailSize =
Op.size() % 16;
19566 if (TailSize > 2 && TailSize <= 4) {
19571 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19576 if (Subtarget.isPPC64()) {
19587 assert(Ty->isIntegerTy());
19589 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19590 return !(BitSize == 0 || BitSize > 64);
19598 return NumBits1 == 64 && NumBits2 == 32;
19606 return NumBits1 == 64 && NumBits2 == 32;
19613 EVT MemVT = LD->getMemoryVT();
19614 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19615 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19631 "invalid fpext types");
19633 if (DestVT == MVT::f128)
19648 unsigned *
Fast)
const {
19662 !Subtarget.allowsUnalignedFPAccess())
19666 if (Subtarget.hasVSX()) {
19667 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19668 VT != MVT::v4f32 && VT != MVT::v4i32)
19675 if (VT == MVT::ppcf128)
19690 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19698 int64_t
Imm = ConstNode->getSExtValue();
19703 uint64_t UImm =
static_cast<uint64_t
>(
Imm);
19719 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19721 switch (Ty->getScalarType()->getTypeID()) {
19726 return Subtarget.hasP9Vector();
19734 if (!
I->hasOneUse())
19738 assert(
User &&
"A single use instruction with no uses.");
19740 switch (
I->getOpcode()) {
19741 case Instruction::FMul: {
19743 if (
User->getOpcode() != Instruction::FSub &&
19744 User->getOpcode() != Instruction::FAdd)
19750 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19751 User->getFastMathFlags().allowContract();
19757 case Instruction::Load: {
19770 if (
User->getOpcode() != Instruction::Store)
19790 static const MCPhysReg ScratchRegs[] = {
19791 PPC::X12, PPC::LR8, PPC::CTR8, 0
19794 return ScratchRegs;
19799 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19804 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19809 EVT VT ,
unsigned DefinedValues)
const {
19810 if (VT == MVT::v2i64)
19811 return Subtarget.hasDirectMove();
19813 if (Subtarget.hasVSX())
19840 return PPCISD::FNMSUB;
19841 case PPCISD::FNMSUB:
19847 bool LegalOps,
bool OptForSize,
19849 unsigned Depth)
const {
19853 unsigned Opc =
Op.getOpcode();
19854 EVT VT =
Op.getValueType();
19858 case PPCISD::FNMSUB:
19878 if (Flags.hasNoSignedZeros()) {
19882 N0Cost,
Depth + 1);
19886 N1Cost,
Depth + 1);
19888 if (NegN0 && N0Cost <= N1Cost) {
19889 Cost = std::min(N0Cost, N2Cost);
19891 }
else if (NegN1) {
19892 Cost = std::min(N1Cost, N2Cost);
19912 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19918 bool ForCodeSize)
const {
19919 if (!VT.
isSimple() || !Subtarget.hasVSX())
19929 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19934 APSInt IntResult(16,
false);
19939 if (IsExact && IntResult <= 15 && IntResult >= -16)
19941 return Imm.isZero();
19944 return Imm.isPosZero();
19956 unsigned Opcode =
N->getOpcode();
19976 if (Mask->getZExtValue() == OpSizeInBits - 1)
19983 DAGCombinerInfo &DCI)
const {
19984 EVT VT =
N->getValueType(0);
19987 unsigned Opc =
N->getOpcode();
19989 "Unexpected opcode.");
19996 if (EltTy != MVT::i64 && EltTy != MVT::i32)
20001 bool AddSplatCase =
false;
20005 AddSplatCase =
true;
20009 if (!AddSplatCase) {
20013 unsigned SplatBitSize;
20015 APInt APSplatBits, APSplatUndef;
20017 bool BVNIsConstantSplat =
20019 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
20020 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
20031 if (SplatBits == (EltBits - 1)) {
20035 NewOpc = PPCISD::SHL;
20038 NewOpc = PPCISD::SRL;
20041 NewOpc = PPCISD::SRA;
20045 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
20053 if (EltTy != MVT::i64 || SplatBits != 1)
20056 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
20059SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20063 if (
N->getValueType(0).isVector())
20064 return combineVectorShift(
N, DCI);
20068 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
20071 N->getValueType(0) != MVT::i64)
20086 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
20092SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20096 if (
N->getValueType(0).isVector())
20097 return combineVectorShift(
N, DCI);
20102SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20106 if (
N->getValueType(0).isVector())
20107 return combineVectorShift(
N, DCI);
20118 if (!Subtarget.isPPC64())
20124 auto isZextOfCompareWithConstant = [](
SDValue Op) {
20126 Op.getValueType() != MVT::i64)
20130 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
20131 Cmp.getOperand(0).getValueType() != MVT::i64)
20135 int64_t NegConstant = 0 -
Constant->getSExtValue();
20144 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
20145 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
20148 if (LHSHasPattern && !RHSHasPattern)
20150 else if (!LHSHasPattern && !RHSHasPattern)
20154 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
20157 SDValue Z = Cmp.getOperand(0);
20159 int64_t NegConstant = 0 -
Constant->getSExtValue();
20172 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20190 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20220 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20223 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20231 if (!GSDN || !ConstNode)
20259 EVT VT =
N->getValueType(0);
20260 if (!Subtarget.hasVSX())
20264 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20276 unsigned NumOfEles =
RHS.getNumOperands();
20277 for (
unsigned i = 0; i < NumOfEles; ++i) {
20279 if (!CN || CN->getSExtValue() != 1)
20294SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20316 DAGCombinerInfo &DCI)
const {
20318 if (Subtarget.useCRBits()) {
20320 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20321 return CRTruncValue;
20328 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20331 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20341 EltToExtract = EltToExtract ? 0 : 1;
20351 return DCI.DAG.getNode(
20353 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20358SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20359 SelectionDAG &DAG = DCI.DAG;
20362 if (!ConstOpOrElement)
20370 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20371 switch (this->Subtarget.getCPUDirective()) {
20394 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20398 EVT VT =
N->getValueType(0);
20403 APInt MulAmtAbs = MulAmt.
abs();
20405 if ((MulAmtAbs - 1).isPowerOf2()) {
20409 if (!IsProfitable(IsNeg,
true, VT))
20422 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20426 if (!IsProfitable(IsNeg,
false, VT))
20447 DAGCombinerInfo &DCI)
const {
20451 SDNodeFlags
Flags =
N->getFlags();
20452 EVT VT =
N->getValueType(0);
20453 SelectionDAG &DAG = DCI.DAG;
20454 unsigned Opc =
N->getOpcode();
20456 bool LegalOps = !DCI.isBeforeLegalizeOps();
20464 if (!
Flags.hasNoSignedZeros())
20480bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20482 if (!Subtarget.is64BitELFABI())
20492 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
20497 if (!Callee ||
Callee->isVarArg())
20510bool PPCTargetLowering::
20511isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20516 if (CI->getBitWidth() > 64)
20518 int64_t ConstVal = CI->getZExtValue();
20520 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20529PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20535 if ((Flags & FlagSet) == FlagSet)
20538 if ((Flags & FlagSet) == FlagSet)
20541 if ((Flags & FlagSet) == FlagSet)
20544 if ((Flags & FlagSet) == FlagSet)
20565 if ((FrameIndexAlign % 4) != 0)
20566 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20567 if ((FrameIndexAlign % 16) != 0)
20568 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20572 if ((FrameIndexAlign % 4) == 0)
20574 if ((FrameIndexAlign % 16) == 0)
20588 if ((
Imm & 0x3) == 0)
20590 if ((
Imm & 0xf) == 0)
20596 const APInt &ConstImm = CN->getAPIntValue();
20615 const APInt &ConstImm = CN->getAPIntValue();
20625 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20636 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20645unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20650 if (!Subtarget.hasP9Vector())
20655 if (Subtarget.hasPrefixInstrs())
20658 if (Subtarget.hasSPE())
20667 unsigned ParentOp = Parent->
getOpcode();
20671 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
20672 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20684 if (LSB->isIndexed())
20690 assert(MN &&
"Parent should be a MemSDNode!");
20695 "Not expecting scalar integers larger than 16 bytes!");
20698 else if (
Size == 32)
20705 else if (
Size == 256) {
20706 assert(Subtarget.pairedVectorMemops() &&
20707 "256-bit vectors are only available when paired vector memops is "
20715 else if (MemVT == MVT::f128 || MemVT.
isVector())
20746 FlagSet &= ~PPC::MOF_NoExt;
20751 bool IsNonP1034BitConst =
20755 IsNonP1034BitConst)
20768 int16_t ForceXFormImm = 0;
20771 Disp =
N.getOperand(0);
20772 Base =
N.getOperand(1);
20783 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20784 Disp =
N.getOperand(0);
20785 Base =
N.getOperand(1);
20790 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20799 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20805 if (PartVT == MVT::f64 &&
20806 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20815SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20819 EVT RetVT =
Op.getValueType();
20826 EVT ArgVT =
N.getValueType();
20830 Entry.IsZExt = !Entry.IsSExt;
20831 Args.push_back(Entry);
20839 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20852SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20853 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20855 if (
Op.getValueType() == MVT::f32)
20856 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20858 if (
Op.getValueType() == MVT::f64)
20859 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20864bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20865 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20866 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20870bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20871 return Op.getNode()->getFlags().hasApproximateFuncs();
20874bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20879SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20880 const char *LibCallFloatName,
20881 const char *LibCallDoubleNameFinite,
20882 const char *LibCallFloatNameFinite,
20885 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20888 if (!isLowringToMASSFiniteSafe(
Op))
20889 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20892 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20893 LibCallDoubleNameFinite,
Op, DAG);
20897 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20898 "__xl_powf_finite",
Op, DAG);
20902 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20903 "__xl_sinf_finite",
Op, DAG);
20907 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20908 "__xl_cosf_finite",
Op, DAG);
20912 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20913 "__xl_logf_finite",
Op, DAG);
20917 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20918 "__xl_log10f_finite",
Op, DAG);
20922 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20923 "__xl_expf_finite",
Op, DAG);
20948 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20959 assert(Subtarget.isUsingPCRelativeCalls() &&
20960 "Must be using PC-Relative calls when a valid PC-Relative node is "
20990 Disp =
N.getOperand(1).getOperand(0);
20995 Base =
N.getOperand(0);
21003 EVT CNType = CN->getValueType(0);
21004 uint64_t CNImm = CN->getZExtValue();
21015 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
21017 int32_t Addr = (int32_t)CNImm;
21022 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
21038 unsigned Opcode =
N.getOpcode();
21046 Base =
N.getOperand(0);
21065 Base = FI ?
N :
N.getOperand(1);
21066 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
21077 bool IsVarArg)
const {
21087 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
21124 return Intrinsic::ppc_atomicrmw_xchg_i128;
21126 return Intrinsic::ppc_atomicrmw_add_i128;
21128 return Intrinsic::ppc_atomicrmw_sub_i128;
21130 return Intrinsic::ppc_atomicrmw_and_i128;
21132 return Intrinsic::ppc_atomicrmw_or_i128;
21134 return Intrinsic::ppc_atomicrmw_xor_i128;
21136 return Intrinsic::ppc_atomicrmw_nand_i128;
21144 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21148 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
21150 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
21151 Value *LoHi = Builder.CreateIntrinsic(
21153 {AlignedAddr, IncrLo, IncrHi});
21154 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21155 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21156 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21157 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21158 return Builder.CreateOr(
21159 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21166 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21172 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
21174 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
21175 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
21177 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
21180 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
21182 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21183 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21184 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21185 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21186 return Builder.CreateOr(
21187 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21191 return Subtarget.useCRBits();
21196bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
21207 DAGCombinerInfo &DCI)
const {
21212 EVT ResVT =
N->getValueType(0);
21214 EVT SrcVT = Src.getValueType();
21219 if (ResVT != MVT::i16 && ResVT != MVT::i8)
21222 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
21235 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
21236 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
21237 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
21239 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
21247 SmallVector<int, 16> BitIndices(16, 128);
21251 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
21252 if (IsV8i8 && IsLE)
21253 BitIndices[Idx] += 64;
21256 std::reverse(BitIndices.begin(), BitIndices.end());
21258 for (
auto Idx : BitIndices)
21263 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
21271 bool BVNIsConstantSplat,
21272 unsigned SplatBitSize)
const {
21274 if (!BVNIsConstantSplat || !Subtarget.hasVSX() || !Subtarget.hasP8Vector() ||
21275 Subtarget.hasP10Vector())
21278 EVT VT =
Op->getValueType(0);
21279 if (!((SplatBitSize == 64 && VT == MVT::v2f64) ||
21280 (SplatBitSize == 32 && VT == MVT::v4f32)))
21287 APFloat APFloatVal = CN->getValueAPF();
21289 APSInt IntResult(16,
false);
21292 if (!(IsExact && IntResult <= 15 && IntResult >= -16 && !APFloatVal.
isZero()))
21295 int64_t
IntVal = IntResult.getSExtValue();
21300 if (SplatBitSize == 64)
21303 DAG.
getConstant(Intrinsic::ppc_vsx_xvcvsxwdp, dl, MVT::i32), IntSplat);
21305 return DAG.
getNode(PPCISD::XVCVSXWSP, dl, MVT::v4f32, IntSplat);
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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).
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 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 MachineBasicBlock * emitAtomicCmpSwapSoftware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit software-emulated atomic compare-and-swap for I8/I16 without hardware partword atomic support.
static SDValue DAGCombineSube(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
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 IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
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 void prepareOutOfLineGlueCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
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 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 IsSelectCC(unsigned Opcode)
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 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 combineXorSelectCC(SDNode *N, SelectionDAG &DAG)
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 bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS, bool IsPPC64)
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 CallInst * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
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 SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG)
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 void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue combineSELECT_CCBitFloor(SDNode *N, SelectionDAG &DAG)
Optimize the bitfloor(X) pattern for PowerPC.
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 MachineBasicBlock * emitSelect(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit SELECT instruction, using ISEL if available, otherwise use branch-based control flow.
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 bool canConvertSETCCToXori(SDNode *N)
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 void createAtomicLoopBlocks(MachineFunction *F, MachineBasicBlock *BB, MachineBasicBlock *&loop1MBB, MachineBasicBlock *&loop2MBB, MachineBasicBlock *&exitMBB, MachineInstr &MI, MachineFunction::iterator It)
Helper function to create basic blocks for atomic compare-and-swap.
cl::opt< bool > EnablePPCGenScalarMASSEntries
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue combineZextSetccWithZero(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...
static MachineBasicBlock * emitAtomicCmpSwapHardware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit hardware-supported atomic compare-and-swap for I32/I64 and I8/I16 with partword atomic support.
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 void signExtendOperandIfUnknown(MachineInstr &MI, MachineBasicBlock *BB, unsigned OpIdx, bool IsByte, const PPCInstrInfo *TII)
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")
This file describes how to lower LLVM code to machine code.
static constexpr int TPOffset
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
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) 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 ult(const APInt &RHS) const
Unsigned less than comparison.
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
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 constexpr BranchProbability getOne()
static constexpr 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].
const Constant * getConstVal() const
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.
Tracks which library functions to use for a particular subtarget or function.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
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.
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...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
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.
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
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.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
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 bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
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 the unique 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()