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()
3071 SDValue
Ops[] = { GA,
Reg };
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()) {
3214 SDValue MatAddr = DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
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;
3320 SDValue VariableOffsetTGA =
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).");
3387 SDValue VariableOffsetTGA =
3389 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3392 GlobalVariable *TLSGV =
3396 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3397 SDValue ModuleHandleTGA =
3399 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3400 SDValue ModuleHandle =
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);
3428 SDValue VariableOffsetTGA =
3430 SDValue RegionHandleTGA =
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()) {
3460 SDValue TLSReg = DAG.
getRegister(PPC::X13, MVT::i64);
3464 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3465 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3472 SDValue TLSReg = is64bit ? DAG.
getRegister(PPC::X13, MVT::i64)
3475 SDValue
Hi = DAG.
getNode(PPCISD::Hi, dl, PtrVT, TGAHi, TLSReg);
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());
3494 SDValue GOTReg = DAG.
getRegister(PPC::X2, MVT::i64);
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);
3521 SDValue GOTReg = DAG.
getRegister(PPC::X2, MVT::i64);
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);
3547 SDValue GOTReg = DAG.
getRegister(PPC::X2, MVT::i64);
3548 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3556 SDValue TLSAddr = DAG.
getNode(PPCISD::ADDI_TLSLD_L_ADDR, dl,
3557 PtrVT, GOTPtr, TGA, TGA);
3558 SDValue DtvOffsetHi = DAG.
getNode(PPCISD::ADDIS_DTPREL_HA, dl,
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()) {
3581 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
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();
3620 SDValue
LHS =
Op.getOperand(IsStrict ? 1 : 0);
3621 SDValue
RHS =
Op.getOperand(IsStrict ? 2 : 1);
3622 SDValue Chain = IsStrict ?
Op.getOperand(0) : SDValue();
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();
3698 SDValue Chain =
Op.getOperand(0);
3700 SDValue
LHS =
Op.getOperand(2);
3701 SDValue
RHS =
Op.getOperand(3);
3702 SDValue Dest =
Op.getOperand(4);
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);
3729 SDValue InChain =
Node->getOperand(0);
3730 SDValue VAListPtr =
Node->getOperand(1);
3734 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3738 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3741 if (VT == MVT::i64) {
3745 SDValue CC64 = DAG.
getSetCC(dl, MVT::i32, GprAnd,
3747 SDValue GprIndexPlusOne = DAG.
getNode(
ISD::ADD, dl, MVT::i32, GprIndex,
3760 FprPtr, MachinePointerInfo(SV), MVT::i8);
3770 SDValue OverflowArea =
3771 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3772 InChain = OverflowArea.
getValue(1);
3774 SDValue RegSaveArea =
3775 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3805 MachinePointerInfo(SV), MVT::i8);
3811 SDValue OverflowAreaPlusN = DAG.
getNode(
ISD::ADD, dl, PtrVT, OverflowArea,
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)
3893 SDValue Chain =
Op.getOperand(0);
3894 SDValue Trmp =
Op.getOperand(1);
3895 SDValue FPtr =
Op.getOperand(2);
3896 SDValue Nest =
Op.getOperand(3);
3901 if (Subtarget.isAIXABI()) {
3906 MaybeAlign PointerAlign(PointerSize);
3907 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3910 : MachineMemOperand::MONone;
3914 SDValue SDTOCPtrOffset = DAG.
getConstant(TOCPointerOffset, dl, PtrVT);
3915 SDValue SDEnvPtrOffset = DAG.
getConstant(EnvPointerOffset, dl, PtrVT);
3917 const Value *TrampolineAddr =
3922 SDValue OutChains[3];
3926 SDValue LoadEntryPoint =
3927 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3928 PointerAlign, MMOFlags);
3929 SDValue EPLoadChain = LoadEntryPoint.
getValue(1);
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 =
3942 SDValue TOCLoadChain = TOCReg.
getValue(1);
3944 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3945 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3949 SDValue EnvPointer = DAG.
getNode(
ISD::ADD, dl, PtrVT, Trmp, SDEnvPtrOffset);
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;
4029 SDValue ConstFrameOffset = DAG.
getConstant(FrameOffset, dl, PtrVT);
4031 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4032 SDValue ConstStackOffset = DAG.
getConstant(StackOffset, dl, PtrVT);
4035 SDValue ConstFPROffset = DAG.
getConstant(FPROffset, dl, PtrVT);
4040 SDValue firstStore =
4042 MachinePointerInfo(SV), MVT::i8);
4048 SDValue secondStore =
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");
4303 SDValue ArgValueLo = DAG.
getCopyFromReg(Chain, dl, RegLo, MVT::i32);
4304 SDValue ArgValueHi = DAG.
getCopyFromReg(Chain, dl, RegHi, MVT::i32);
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);
4410 SDValue PtrOff = DAG.
getConstant(PtrVT.getSizeInBits()/8, dl, PtrVT);
4418 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4422 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4429 SDValue PtrOff = DAG.
getConstant(MVT(MVT::f64).getSizeInBits()/8, dl,
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) {
4600 SDValue ArgOff = DAG.
getConstant(PtrByteSize - ObjSize, dl, PtrVT);
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) {
4822 SDValue PtrOff = DAG.
getConstant(PtrByteSize, dl, PtrVT);
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());
5227 Chain = SDValue(LROpOut.
getNode(), 1);
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);
5795 SDValue PtrGlueCallee =
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.");
5828 SDValue Ret = DAG.
getNode(CallOpc, dl, MVT::Other,
Ops);
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();
6066 SDValue CallSeqStart = Chain;
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++];
6112 SDValue MemcpyCall =
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);
6187 SDValue
Ops[] = { Chain, InGlue };
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)
6393 SDValue CallSeqStart = Chain;
6398 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6409 unsigned ArgOffset = LinkageSize;
6415 for (
unsigned i = 0; i !=
NumOps; ++i) {
6416 SDValue Arg = OutVals[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) {
6488 SDValue AddPtr = PtrOff;
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) {
6521 SDValue AddPtr = PtrOff;
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;
7249 SDValue StoreReg = DAG.
getStore(Chain, dl, Parm, FIN,
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());
7295 SDValue ArgValueTrunc =
7297 SDValue ArgValueExt =
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 =
7545 SDValue PtrOff = DAG.
getConstant(PtrByteSize, dl, PtrVT);
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());
7605 SDValue CallSeqStart = Chain;
7616 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7617 const unsigned ValNo = ArgLocs[
I].getValNo();
7618 SDValue Arg = OutVals[ValNo];
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()) {
7643 SDValue
Load = GetLoad(PtrVT, LoadOffset);
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));
7689 SDValue
Load = GetLoad(VT, LoadOffset);
7698 "Unexpected load emitted during handling of pass-by-value "
7703 SDValue SHLAmt = DAG.
getConstant(NumSHLBits, dl, ShiftAmountTy);
7704 SDValue ShiftedLoad =
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();
7967 SDValue Chain =
Op.getOperand(0);
7968 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7970 SDValue
Ops[2] = {Chain, FPSIdx};
7972 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7984 bool isPPC64 = Subtarget.isPPC64();
7985 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7989 SDValue Chain =
Op.getOperand(0);
7990 SDValue SaveSP =
Op.getOperand(1);
7993 SDValue LoadLinkSP =
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();
8052 SDValue Chain =
Op.getOperand(0);
8053 SDValue
Size =
Op.getOperand(1);
8062 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8063 SDValue
Ops[3] = { Chain, NegSize, FPSIdx };
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");
8108 SDValue Chain =
LD->getChain();
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");
8133 SDValue Chain =
ST->getChain();
8135 SDValue
Value =
ST->getValue();
8136 MachineMemOperand *MMO =
ST->getMemOperand();
8145 assert(
Op.getValueType() == MVT::i1 &&
8146 "Custom lowering only for i1 results");
8174 EVT TrgVT =
Op.getValueType();
8183 SDValue N1 =
Op.getOperand(0);
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();
8239 SDValue
LHS =
Op.getOperand(0),
RHS =
Op.getOperand(1);
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 =
8465 SDValue
Ops[] = { Chain, Tmp, FIPtr };
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 {
8493 SDValue Mov = DAG.
getNode(PPCISD::MFVSR, dl,
Op.getValueType(), Conv);
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());
8530 SDValue Res = DAG.
getNode(PPCISD::STRICT_FADDRTZ, dl,
8532 {Op.getOperand(0), Lo, Hi}, Flags);
8535 {Res.getValue(1), Res}, Flags);
8537 SDValue Res = DAG.
getNode(PPCISD::FADDRTZ, dl, MVT::f64,
Lo,
Hi);
8541 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8544 SDValue SignMask = DAG.
getConstant(0x80000000, dl, DstVT);
8550 SDValue Chain =
Op.getOperand(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;
8737 SDValue Mov = DAG.
getNode(MovOpc, dl, MVT::f64, Src);
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;
8779 SDValue Wide =
widenVec(DAG, Src, dl);
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;
8797 SDValue ShuffleSrc2 =
8799 SDValue Arrange = DAG.
getVectorShuffle(WideVT, dl, Wide, ShuffleSrc2, ShuffV);
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);
8828 SDValue Chain = IsStrict ?
Op.getOperand(0) : DAG.
getEntryNode();
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));
8936 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
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));
8947 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
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));
8981 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
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));
9043 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
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);
9094 SDValue Chain =
Op.getOperand(0);
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,
9112 {DAG.
getConstant(31, Dl, MVT::i32,
true), SDValue(SetHi, 0)});
9113 return SDValue(SetLo, 0);
9120 SDValue DstFlag = DAG.
getNode(
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())
9176 return SDValue(DAG.
getMachineNode(PPC::MFFSCRN, Dl, {MVT::f64, MVT::Other},
9181 PPC::MTFSF, Dl, MVT::Other,
9183 return SDValue(MTFSF, 0);
9209 EVT VT =
Op.getValueType();
9213 SDValue Chain =
Op.getOperand(0);
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() &&
9268 SDValue
Lo =
Op.getOperand(0);
9269 SDValue
Hi =
Op.getOperand(1);
9270 SDValue Amt =
Op.getOperand(2);
9275 SDValue Tmp2 = DAG.
getNode(PPCISD::SHL, dl, VT,
Hi, Amt);
9276 SDValue Tmp3 = DAG.
getNode(PPCISD::SRL, dl, VT,
Lo, Tmp1);
9280 SDValue Tmp6 = DAG.
getNode(PPCISD::SHL, dl, VT,
Lo, Tmp5);
9282 SDValue OutLo = DAG.
getNode(PPCISD::SHL, dl, VT,
Lo, Amt);
9283 SDValue OutOps[] = { OutLo, OutHi };
9288 EVT VT =
Op.getValueType();
9292 VT ==
Op.getOperand(1).getValueType() &&
9297 SDValue
Lo =
Op.getOperand(0);
9298 SDValue
Hi =
Op.getOperand(1);
9299 SDValue Amt =
Op.getOperand(2);
9304 SDValue Tmp2 = DAG.
getNode(PPCISD::SRL, dl, VT,
Lo, Amt);
9305 SDValue Tmp3 = DAG.
getNode(PPCISD::SHL, dl, VT,
Hi, Tmp1);
9309 SDValue Tmp6 = DAG.
getNode(PPCISD::SRL, dl, VT,
Hi, Tmp5);
9311 SDValue OutHi = DAG.
getNode(PPCISD::SRL, dl, VT,
Hi, Amt);
9312 SDValue OutOps[] = { OutLo, OutHi };
9318 EVT VT =
Op.getValueType();
9321 VT ==
Op.getOperand(1).getValueType() &&
9325 SDValue
Lo =
Op.getOperand(0);
9326 SDValue
Hi =
Op.getOperand(1);
9327 SDValue Amt =
Op.getOperand(2);
9332 SDValue Tmp2 = DAG.
getNode(PPCISD::SRL, dl, VT,
Lo, Amt);
9333 SDValue Tmp3 = DAG.
getNode(PPCISD::SHL, dl, VT,
Hi, Tmp1);
9337 SDValue Tmp6 = DAG.
getNode(PPCISD::SRA, dl, VT,
Hi, Tmp5);
9338 SDValue OutHi = DAG.
getNode(PPCISD::SRA, dl, VT,
Hi, Amt);
9341 SDValue OutOps[] = { OutLo, OutHi };
9348 EVT VT =
Op.getValueType();
9352 SDValue
X =
Op.getOperand(0);
9353 SDValue
Y =
Op.getOperand(1);
9354 SDValue
Z =
Op.getOperand(2);
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);
9501 SDValue Op0 =
Op->getOperand(0);
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 =
9665 SDValue SDV = SDValue(MSDNode, 0);
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) &&
9696 SDValue SplatNode = DAG.
getNode(
9697 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9705 SDValue SplatNode = DAG.
getUNDEF(MVT::v2i64);
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;
9774 for (SDValue BVInOp :
Op->ops())
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;
9877 SDValue IntrinsicOp =
9879 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9885 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9886 SDValue
C = DAG.
getConstant((
unsigned char)SextVal, dl, MVT::i32);
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));
9926 SDValue EltSize = DAG.
getConstant(SplatSize, dl, MVT::i32);
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();
10107 SDValue
V1 =
N->getOperand(0);
10108 SDValue V2 =
N->getOperand(1);
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();
10213 SDValue
V1 =
N->getOperand(0);
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);
10380 SDValue SplatNode = DAG.
getNode(
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());
10402 if (SDValue Shuffle =
10407 SDValue ArgVal = DAG.
getBitcast(MVT::i128, N0);
10412 SDValue OROp = DAG.
getNode(
ISD::OR, dl, MVT::i128, SHLOp, SRLOp);
10423 SDValue
V1 =
Op.getOperand(0);
10424 SDValue V2 =
Op.getOperand(1);
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()) {
10528 SDValue SplatInsertNode;
10529 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10530 return SplatInsertNode;
10533 if (Subtarget.hasP9Altivec()) {
10534 SDValue NewISDNode;
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()) {
10593 SDValue
Splat = DAG.
getNode(PPCISD::XXSPLT, dl, MVT::v4i32, Conv,
10601 SDValue
Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
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++;
10818 SDValue VPermMask = DAG.
getBuildVector(MVT::v16i8, dl, ResultMask);
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)
10839 SDValue VPERMNode =
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!");
11162 SDValue Src =
Op.getOperand(1);
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};
11235 SDValue(DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes,
11240 SDValue Value2 = SDValue(WideVec.
getNode(), 1);
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: {
11273 SDValue WideVec =
Op.getOperand(1);
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++) {
11280 SDValue Extract = DAG.
getNode(
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) {
11294 SDValue
Hi =
Op.getOperand(i);
11295 SDValue
Lo =
Op.getOperand(i + 1);
11301 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11304 SDValue
Value = DMFInsert1024(Pairs, SDLoc(
Op), DAG);
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};
11329 return SDValue(DAG.
getMachineNode(Opcode, dl, ReturnTypes, Subreg), 0);
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;
11379 SDValue Wacc = DAG.
getNode(Opcode, dl, MVT::v512i1,
Op.getOperand(2),
11382 return SDValue(DAG.
getMachineNode(PPC::INSERT_SUBREG, dl, MVT::v1024i1,
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);
11412 return SDValue(DAG.
getMachineNode(PPC::INSERT_SUBREG, dl, MVT::v1024i1,
11413 Op.getOperand(1), DMRRowp, SubReg),
11417 case Intrinsic::ppc_mma_xxmfacc:
11418 case Intrinsic::ppc_mma_xxmtacc: {
11420 if (!Subtarget.isISAFuture())
11426 SDValue WideVec =
Op.getOperand(1);
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
11483 SDValue TestDataClass =
11485 {Op.getOperand(2), Op.getOperand(1)}),
11487 if (Subtarget.isISA3_1()) {
11493 SDValue(DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
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)
11547 SDValue Res =
Op.getOperand(
I);
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 };
11578 SDValue CompNode = DAG.
getNode(PPCISD::VCMP_rec, dl, VTs,
Ops);
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;
11613 SDValue GlueOp = CompNode.
getValue(1);
11614 if (Subtarget.isISA3_1()) {
11616 SDValue CR6Reg = DAG.
getRegister(PPC::CR6, MVT::i32);
11618 SDValue(DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
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())
11701 SDValue Input =
Op.getOperand(0);
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())
11717 auto Swap32 = [&](SDValue Val32) -> SDValue {
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();
11752 SDValue CmpOp =
Op.getOperand(2);
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");
11969 SDValue
LHS =
Op.getOperand(0);
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();
12006 SDValue
Ops[] = {VPLD->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
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());
12040 SDValue Acc =
Op.getOperand(0);
12041 SDValue Op1 =
Op.getOperand(1);
12042 SDValue Op2 =
Op.getOperand(2);
12045 "Unexpected partial reduction");
12056 SDValue Ones = DAG.
getConstant(1, dl, MVT::v16i8);
12066 SDValue Op0 =
Op.getOperand(0);
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);
12118 SDValue
Store = DAG.
getStore(Store2, dl, Val, FIdx, MachinePointerInfo());
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();
12139 SDValue
V1 =
Op.getOperand(0);
12140 SDValue V2 =
Op.getOperand(1);
12142 if (VT == MVT::v2f64 &&
C)
12145 if (Subtarget.hasP9Vector()) {
12154 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12156 SDValue BitcastVector = DAG.
getBitcast(MVT::v4i32,
V1);
12157 SDValue BitcastLoad = DAG.
getBitcast(MVT::i32, V2);
12158 SDValue InsVecElt =
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) {
12182 SDValue Mtvsrz = DAG.
getNode(PPCISD::MTVSRZ, dl, VT, V2);
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,
12199 SDValue LoadChain = LN->
getChain();
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.");
12216 SDValue IntrinID = DAG.
getConstant(Intrinsic::ppc_vsx_lxvp, dl, MVT::i32);
12217 SDValue LoadOps[] = {LoadChain, IntrinID,
BasePtr};
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());
12241 SDValue
Value = DMFInsert1024(Loads, dl, DAG);
12249 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12255 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12257 SDValue DmrPValue = SDValue(
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]);
12274 return SDValue(DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1,
12275 {RC, Lo, LoSub, Hi, HiSub}),
12283 SDValue LoadChain = LN->
getChain();
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,
12329 SDValue RetOps[] = {
Value, TF};
12338 SDValue StoreChain = SN->
getChain();
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 =
12368 Values.push_back(SDValue(ExtNode, 0));
12369 Values.push_back(SDValue(ExtNode, 1));
12370 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12371 Values.push_back(SDValue(ExtNode, 0));
12372 Values.push_back(SDValue(ExtNode, 1));
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);
12409 Values.push_back(SDValue(ExtNode, 0));
12410 Values.push_back(SDValue(ExtNode, 1));
12412 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12413 Values.push_back(SDValue(ExtNode, 0));
12414 Values.push_back(SDValue(ExtNode, 1));
12415 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12416 Values.push_back(SDValue(ExtNode, 0));
12417 Values.push_back(SDValue(ExtNode, 1));
12419 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12420 Values.push_back(SDValue(ExtNode, 0));
12421 Values.push_back(SDValue(ExtNode, 1));
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);
12455 SDValue StoreChain = SN->
getChain();
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));
12490 Value = SDValue(ExtNode, 0);
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) {
12524 SDValue
LHS =
Op.getOperand(0),
RHS =
Op.getOperand(1);
12540 LHS,
RHS, DAG, dl, MVT::v4i32);
12543 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12548 }
else if (
Op.getValueType() == MVT::v16i8) {
12549 SDValue
LHS =
Op.getOperand(0),
RHS =
Op.getOperand(1);
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)
12607 SDValue Op0 =
Op.getOperand(0);
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,
12639 SDValue NewLoad[2];
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);
12744 SDValue
LHS =
Op.getOperand(0);
12745 SDValue
RHS =
Op.getOperand(1);
12746 EVT VT =
Op.getNode()->getValueType(0);
12759 SDValue OverflowTrunc =
12770 SDValue
LHS =
Op.getOperand(0);
12771 SDValue
RHS =
Op.getOperand(1);
12772 EVT VT =
Op.getNode()->getValueType(0);
12778 SDValue EqvXY = DAG.
getNOT(dl, XorXY, VT);
12783 SDValue OverflowInSign = DAG.
getNode(
ISD::AND, dl, VT, EqvXY, SumXorX);
12790 SDValue OverflowTrunc =
12802 SDValue
LHS =
Op.getOperand(0);
12803 SDValue
RHS =
Op.getOperand(1);
12804 EVT OpVT =
LHS.getValueType();
12805 EVT VT =
Op.getValueType();
12820 unsigned Opcode = PPCISD::SUBC;
12826 SDValue SubLHS =
RHS.getOperand(0);
12827 SDValue SubRHS =
RHS.getOperand(1);
12830 Opcode = PPCISD::ADDC;
12837 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12844 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12849 SDValue ZeroOrNeg1 = DAG.
getNode(PPCISD::SUBE,
DL, VTs, Res, Res, CA0);
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);
12881 SDValue SubC = DAG.
getNode(PPCISD::SUBC,
DL, VTs,
B,
A);
12885 SDValue SubE1 = DAG.
getNode(PPCISD::SUBE,
DL, VTs,
A,
B, CA0);
12889 SDValue ResPair = DAG.
getNode(PPCISD::SUBE,
DL, VTs, Diff, SubE1, CA1);
12906 SDValue
LHS =
Op.getOperand(0);
12907 SDValue
RHS =
Op.getOperand(1);
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;
12928 SDValue CR7Reg = DAG.
getRegister(PPC::CR7, MVT::i32);
12935 unsigned MFOCRFOpc = Use64BitOps ? PPC::MFOCRF8 : PPC::MFOCRF;
12936 EVT MFVT = Use64BitOps ? MVT::i64 : MVT::i32;
12947 unsigned RLWinmOpc = Use64BitOps ? PPC::RLWINM8 : PPC::RLWINM;
12953 SDValue LTBit = SDValue(DAG.
getMachineNode(RLWinmOpc,
DL, MFVT, LTOps), 0);
12959 SDValue GTBit = SDValue(DAG.
getMachineNode(RLWinmOpc,
DL, MFVT, GTOps), 0);
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())))
15123 SDValue FTSQRT = DAG.
getNode(PPCISD::FTSQRT,
DL, MVT::i32,
Op, Flags);
15136 return SDValue(DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG,
DL, MVT::i1,
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);
15752 return SDValue(
N, 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()) {
15941 SDValue PromOp = PromOpHandles.back().
getValue();
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;
16287 SDValue Sube = DAG.
getNode(PPCISD::SUBE, dl, DAG.
getVTList(OpVT, 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");
16309 SDValue
LHS =
N->getOperand(0);
16310 SDValue
RHS =
N->getOperand(1);
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) {
16551 SDValue LxvkqInstr =
16554 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16555 LxvkqInstr.
dump());
16559 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16565 SDValue ShiftAmountVec =
16570 SDValue ShiftVec = SDValue(
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);
16983 SDValue WidthConst =
16987 SDValue
Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16990 Ops, MVT::i8, LDN->getMemOperand());
16995 SDValue ExtOps[] = { Ld, WidthConst };
16996 SDValue Ext = DAG.
getNode(PPCISD::VEXTS, dl, MVT::f64, ExtOps);
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) {
17042 SDValue Tmp = DAG.
getNode(FCTOp, dl, MVT::f64, Src);
17043 SDValue
FP = DAG.
getNode(FCFOp, dl, FCFTy, Tmp);
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();
17403 SDValue Res(SVN, 0);
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);
17503 SDValue TheSplat = IsLittleEndian ?
RHS :
LHS;
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;
19119 if (Subtarget.isAIXABI() && !Subtarget.isAIXExtendedAltivecABI()) {
19120 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
19121 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
19122 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
19123 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
19124 "default AIX AltiVec ABI and cannot be used\n";
19134 std::vector<SDValue> &
Ops,
19139 if (Constraint.
size() > 1)
19142 char Letter = Constraint[0];
19157 EVT TCVT = MVT::i64;
19198 if (Result.getNode()) {
19199 Ops.push_back(Result);
19210 if (
I.getNumOperands() <= 1)
19214 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
19215 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
19216 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
19219 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
19235 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
19247 switch (AM.
Scale) {
19275 unsigned Depth =
Op.getConstantOperandVal(0);
19299 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19307 unsigned Depth =
Op.getConstantOperandVal(0);
19314 bool isPPC64 = PtrVT == MVT::i64;
19320 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19322 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19328 FrameAddr, MachinePointerInfo());
19332#define GET_REGISTER_MATCHER
19333#include "PPCGenAsmMatcher.inc"
19337 bool IsPPC64 = Subtarget.isPPC64();
19349 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19355 Reg = Reg.id() - PPC::R0 + PPC::X0;
19362 if (Subtarget.is32BitELFABI())
19367 if (Subtarget.isAIXABI())
19381 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19397 case Intrinsic::ppc_atomicrmw_xchg_i128:
19398 case Intrinsic::ppc_atomicrmw_add_i128:
19399 case Intrinsic::ppc_atomicrmw_sub_i128:
19400 case Intrinsic::ppc_atomicrmw_nand_i128:
19401 case Intrinsic::ppc_atomicrmw_and_i128:
19402 case Intrinsic::ppc_atomicrmw_or_i128:
19403 case Intrinsic::ppc_atomicrmw_xor_i128:
19404 case Intrinsic::ppc_cmpxchg_i128:
19406 Info.memVT = MVT::i128;
19407 Info.ptrVal =
I.getArgOperand(0);
19409 Info.align =
Align(16);
19414 case Intrinsic::ppc_atomic_load_i128:
19416 Info.memVT = MVT::i128;
19417 Info.ptrVal =
I.getArgOperand(0);
19419 Info.align =
Align(16);
19423 case Intrinsic::ppc_atomic_store_i128:
19425 Info.memVT = MVT::i128;
19426 Info.ptrVal =
I.getArgOperand(2);
19428 Info.align =
Align(16);
19432 case Intrinsic::ppc_altivec_lvx:
19433 case Intrinsic::ppc_altivec_lvxl:
19434 case Intrinsic::ppc_altivec_lvebx:
19435 case Intrinsic::ppc_altivec_lvehx:
19436 case Intrinsic::ppc_altivec_lvewx:
19437 case Intrinsic::ppc_vsx_lxvd2x:
19438 case Intrinsic::ppc_vsx_lxvw4x:
19439 case Intrinsic::ppc_vsx_lxvd2x_be:
19440 case Intrinsic::ppc_vsx_lxvw4x_be:
19441 case Intrinsic::ppc_vsx_lxvl:
19442 case Intrinsic::ppc_vsx_lxvll: {
19445 case Intrinsic::ppc_altivec_lvebx:
19448 case Intrinsic::ppc_altivec_lvehx:
19451 case Intrinsic::ppc_altivec_lvewx:
19454 case Intrinsic::ppc_vsx_lxvd2x:
19455 case Intrinsic::ppc_vsx_lxvd2x_be:
19465 Info.ptrVal =
I.getArgOperand(0);
19468 Info.align =
Align(1);
19473 case Intrinsic::ppc_altivec_stvx:
19474 case Intrinsic::ppc_altivec_stvxl:
19475 case Intrinsic::ppc_altivec_stvebx:
19476 case Intrinsic::ppc_altivec_stvehx:
19477 case Intrinsic::ppc_altivec_stvewx:
19478 case Intrinsic::ppc_vsx_stxvd2x:
19479 case Intrinsic::ppc_vsx_stxvw4x:
19480 case Intrinsic::ppc_vsx_stxvd2x_be:
19481 case Intrinsic::ppc_vsx_stxvw4x_be:
19482 case Intrinsic::ppc_vsx_stxvl:
19483 case Intrinsic::ppc_vsx_stxvll: {
19486 case Intrinsic::ppc_altivec_stvebx:
19489 case Intrinsic::ppc_altivec_stvehx:
19492 case Intrinsic::ppc_altivec_stvewx:
19495 case Intrinsic::ppc_vsx_stxvd2x:
19496 case Intrinsic::ppc_vsx_stxvd2x_be:
19506 Info.ptrVal =
I.getArgOperand(1);
19509 Info.align =
Align(1);
19514 case Intrinsic::ppc_stdcx:
19515 case Intrinsic::ppc_stwcx:
19516 case Intrinsic::ppc_sthcx:
19517 case Intrinsic::ppc_stbcx: {
19519 auto Alignment =
Align(8);
19521 case Intrinsic::ppc_stdcx:
19524 case Intrinsic::ppc_stwcx:
19526 Alignment =
Align(4);
19528 case Intrinsic::ppc_sthcx:
19530 Alignment =
Align(2);
19532 case Intrinsic::ppc_stbcx:
19534 Alignment =
Align(1);
19539 Info.ptrVal =
I.getArgOperand(0);
19541 Info.align = Alignment;
19559 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19560 if (
Op.isMemset() && Subtarget.hasVSX()) {
19561 uint64_t TailSize =
Op.size() % 16;
19565 if (TailSize > 2 && TailSize <= 4) {
19570 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19575 if (Subtarget.isPPC64()) {
19586 assert(Ty->isIntegerTy());
19588 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19589 return !(BitSize == 0 || BitSize > 64);
19597 return NumBits1 == 64 && NumBits2 == 32;
19605 return NumBits1 == 64 && NumBits2 == 32;
19612 EVT MemVT = LD->getMemoryVT();
19613 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19614 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19630 "invalid fpext types");
19632 if (DestVT == MVT::f128)
19647 unsigned *
Fast)
const {
19661 !Subtarget.allowsUnalignedFPAccess())
19665 if (Subtarget.hasVSX()) {
19666 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19667 VT != MVT::v4f32 && VT != MVT::v4i32)
19674 if (VT == MVT::ppcf128)
19689 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19697 int64_t
Imm = ConstNode->getSExtValue();
19702 uint64_t UImm =
static_cast<uint64_t
>(
Imm);
19718 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19720 switch (Ty->getScalarType()->getTypeID()) {
19725 return Subtarget.hasP9Vector();
19733 if (!
I->hasOneUse())
19737 assert(
User &&
"A single use instruction with no uses.");
19739 switch (
I->getOpcode()) {
19740 case Instruction::FMul: {
19742 if (
User->getOpcode() != Instruction::FSub &&
19743 User->getOpcode() != Instruction::FAdd)
19749 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19750 User->getFastMathFlags().allowContract();
19756 case Instruction::Load: {
19769 if (
User->getOpcode() != Instruction::Store)
19789 static const MCPhysReg ScratchRegs[] = {
19790 PPC::X12, PPC::LR8, PPC::CTR8, 0
19793 return ScratchRegs;
19798 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19803 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19808 EVT VT ,
unsigned DefinedValues)
const {
19809 if (VT == MVT::v2i64)
19810 return Subtarget.hasDirectMove();
19812 if (Subtarget.hasVSX())
19839 return PPCISD::FNMSUB;
19840 case PPCISD::FNMSUB:
19846 bool LegalOps,
bool OptForSize,
19848 unsigned Depth)
const {
19852 unsigned Opc =
Op.getOpcode();
19853 EVT VT =
Op.getValueType();
19857 case PPCISD::FNMSUB:
19877 if (Flags.hasNoSignedZeros()) {
19881 N0Cost,
Depth + 1);
19885 N1Cost,
Depth + 1);
19887 if (NegN0 && N0Cost <= N1Cost) {
19888 Cost = std::min(N0Cost, N2Cost);
19890 }
else if (NegN1) {
19891 Cost = std::min(N1Cost, N2Cost);
19911 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19917 bool ForCodeSize)
const {
19918 if (!VT.
isSimple() || !Subtarget.hasVSX())
19928 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19933 APSInt IntResult(16,
false);
19938 if (IsExact && IntResult <= 15 && IntResult >= -16)
19940 return Imm.isZero();
19943 return Imm.isPosZero();
19955 unsigned Opcode =
N->getOpcode();
19975 if (Mask->getZExtValue() == OpSizeInBits - 1)
19982 DAGCombinerInfo &DCI)
const {
19983 EVT VT =
N->getValueType(0);
19986 unsigned Opc =
N->getOpcode();
19988 "Unexpected opcode.");
19995 if (EltTy != MVT::i64 && EltTy != MVT::i32)
20000 bool AddSplatCase =
false;
20004 AddSplatCase =
true;
20008 if (!AddSplatCase) {
20012 unsigned SplatBitSize;
20014 APInt APSplatBits, APSplatUndef;
20016 bool BVNIsConstantSplat =
20018 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
20019 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
20030 if (SplatBits == (EltBits - 1)) {
20034 NewOpc = PPCISD::SHL;
20037 NewOpc = PPCISD::SRL;
20040 NewOpc = PPCISD::SRA;
20044 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
20052 if (EltTy != MVT::i64 || SplatBits != 1)
20055 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
20058SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20062 if (
N->getValueType(0).isVector())
20063 return combineVectorShift(
N, DCI);
20067 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
20070 N->getValueType(0) != MVT::i64)
20081 SDValue ShiftBy = SDValue(CN1, 0);
20085 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
20091SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20095 if (
N->getValueType(0).isVector())
20096 return combineVectorShift(
N, DCI);
20101SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20105 if (
N->getValueType(0).isVector())
20106 return combineVectorShift(
N, DCI);
20117 if (!Subtarget.isPPC64())
20123 auto isZextOfCompareWithConstant = [](
SDValue Op) {
20125 Op.getValueType() != MVT::i64)
20129 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
20130 Cmp.getOperand(0).getValueType() != MVT::i64)
20134 int64_t NegConstant = 0 -
Constant->getSExtValue();
20143 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
20144 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
20147 if (LHSHasPattern && !RHSHasPattern)
20149 else if (!LHSHasPattern && !RHSHasPattern)
20153 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
20156 SDValue Z = Cmp.getOperand(0);
20158 int64_t NegConstant = 0 -
Constant->getSExtValue();
20171 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20189 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20219 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20222 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20230 if (!GSDN || !ConstNode)
20258 EVT VT =
N->getValueType(0);
20259 if (!Subtarget.hasVSX())
20263 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20275 unsigned NumOfEles =
RHS.getNumOperands();
20276 for (
unsigned i = 0; i < NumOfEles; ++i) {
20278 if (!CN || CN->getSExtValue() != 1)
20293SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20315 DAGCombinerInfo &DCI)
const {
20317 if (Subtarget.useCRBits()) {
20319 if (SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20320 return CRTruncValue;
20327 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20330 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20340 EltToExtract = EltToExtract ? 0 : 1;
20350 return DCI.DAG.getNode(
20352 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20357SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20358 SelectionDAG &DAG = DCI.DAG;
20361 if (!ConstOpOrElement)
20369 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20370 switch (this->Subtarget.getCPUDirective()) {
20393 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20397 EVT VT =
N->getValueType(0);
20402 APInt MulAmtAbs = MulAmt.
abs();
20404 if ((MulAmtAbs - 1).isPowerOf2()) {
20408 if (!IsProfitable(IsNeg,
true, VT))
20421 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20425 if (!IsProfitable(IsNeg,
false, VT))
20446 DAGCombinerInfo &DCI)
const {
20450 SDNodeFlags
Flags =
N->getFlags();
20451 EVT VT =
N->getValueType(0);
20452 SelectionDAG &DAG = DCI.DAG;
20453 unsigned Opc =
N->getOpcode();
20455 bool LegalOps = !DCI.isBeforeLegalizeOps();
20463 if (!
Flags.hasNoSignedZeros())
20479bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20481 if (!Subtarget.is64BitELFABI())
20491 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
20496 if (!Callee ||
Callee->isVarArg())
20509bool PPCTargetLowering::
20510isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20515 if (CI->getBitWidth() > 64)
20517 int64_t ConstVal = CI->getZExtValue();
20519 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20528PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20534 if ((Flags & FlagSet) == FlagSet)
20537 if ((Flags & FlagSet) == FlagSet)
20540 if ((Flags & FlagSet) == FlagSet)
20543 if ((Flags & FlagSet) == FlagSet)
20564 if ((FrameIndexAlign % 4) != 0)
20565 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20566 if ((FrameIndexAlign % 16) != 0)
20567 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20571 if ((FrameIndexAlign % 4) == 0)
20573 if ((FrameIndexAlign % 16) == 0)
20587 if ((
Imm & 0x3) == 0)
20589 if ((
Imm & 0xf) == 0)
20595 const APInt &ConstImm = CN->getAPIntValue();
20614 const APInt &ConstImm = CN->getAPIntValue();
20624 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20635 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20644unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20649 if (!Subtarget.hasP9Vector())
20654 if (Subtarget.hasPrefixInstrs())
20657 if (Subtarget.hasSPE())
20666 unsigned ParentOp = Parent->
getOpcode();
20670 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
20671 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20683 if (LSB->isIndexed())
20689 assert(MN &&
"Parent should be a MemSDNode!");
20694 "Not expecting scalar integers larger than 16 bytes!");
20697 else if (
Size == 32)
20704 else if (
Size == 256) {
20705 assert(Subtarget.pairedVectorMemops() &&
20706 "256-bit vectors are only available when paired vector memops is "
20714 else if (MemVT == MVT::f128 || MemVT.
isVector())
20745 FlagSet &= ~PPC::MOF_NoExt;
20750 bool IsNonP1034BitConst =
20754 IsNonP1034BitConst)
20767 int16_t ForceXFormImm = 0;
20770 Disp =
N.getOperand(0);
20771 Base =
N.getOperand(1);
20782 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20783 Disp =
N.getOperand(0);
20784 Base =
N.getOperand(1);
20789 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20798 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20804 if (PartVT == MVT::f64 &&
20805 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20814SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20818 EVT RetVT =
Op.getValueType();
20825 EVT ArgVT =
N.getValueType();
20829 Entry.IsZExt = !Entry.IsSExt;
20830 Args.push_back(Entry);
20838 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20851SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20852 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20854 if (
Op.getValueType() == MVT::f32)
20855 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20857 if (
Op.getValueType() == MVT::f64)
20858 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20863bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20864 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20865 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20869bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20870 return Op.getNode()->getFlags().hasApproximateFuncs();
20873bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20878SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20879 const char *LibCallFloatName,
20880 const char *LibCallDoubleNameFinite,
20881 const char *LibCallFloatNameFinite,
20884 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20887 if (!isLowringToMASSFiniteSafe(
Op))
20888 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20891 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20892 LibCallDoubleNameFinite,
Op, DAG);
20896 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20897 "__xl_powf_finite",
Op, DAG);
20901 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20902 "__xl_sinf_finite",
Op, DAG);
20906 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20907 "__xl_cosf_finite",
Op, DAG);
20911 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20912 "__xl_logf_finite",
Op, DAG);
20916 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20917 "__xl_log10f_finite",
Op, DAG);
20921 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20922 "__xl_expf_finite",
Op, DAG);
20947 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20958 assert(Subtarget.isUsingPCRelativeCalls() &&
20959 "Must be using PC-Relative calls when a valid PC-Relative node is "
20989 Disp =
N.getOperand(1).getOperand(0);
20994 Base =
N.getOperand(0);
21002 EVT CNType = CN->getValueType(0);
21003 uint64_t CNImm = CN->getZExtValue();
21014 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
21016 int32_t Addr = (int32_t)CNImm;
21021 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
21037 unsigned Opcode =
N.getOpcode();
21045 Base =
N.getOperand(0);
21064 Base = FI ?
N :
N.getOperand(1);
21065 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
21076 bool IsVarArg)
const {
21086 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
21123 return Intrinsic::ppc_atomicrmw_xchg_i128;
21125 return Intrinsic::ppc_atomicrmw_add_i128;
21127 return Intrinsic::ppc_atomicrmw_sub_i128;
21129 return Intrinsic::ppc_atomicrmw_and_i128;
21131 return Intrinsic::ppc_atomicrmw_or_i128;
21133 return Intrinsic::ppc_atomicrmw_xor_i128;
21135 return Intrinsic::ppc_atomicrmw_nand_i128;
21143 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21147 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
21149 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
21150 Value *LoHi = Builder.CreateIntrinsic(
21152 {AlignedAddr, IncrLo, IncrHi});
21153 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21154 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21155 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21156 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21157 return Builder.CreateOr(
21158 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21165 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
21171 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
21173 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
21174 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
21176 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
21179 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
21181 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21182 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21183 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21184 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21185 return Builder.CreateOr(
21186 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21190 return Subtarget.useCRBits();
21195bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
21206 DAGCombinerInfo &DCI)
const {
21211 EVT ResVT =
N->getValueType(0);
21213 EVT SrcVT = Src.getValueType();
21218 if (ResVT != MVT::i16 && ResVT != MVT::i8)
21221 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
21234 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
21235 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
21236 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
21238 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
21246 SmallVector<int, 16> BitIndices(16, 128);
21250 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
21251 if (IsV8i8 && IsLE)
21252 BitIndices[Idx] += 64;
21255 std::reverse(BitIndices.begin(), BitIndices.end());
21257 for (
auto Idx : BitIndices)
21262 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
21270 bool BVNIsConstantSplat,
21271 unsigned SplatBitSize)
const {
21273 if (!BVNIsConstantSplat || !Subtarget.hasVSX() || !Subtarget.hasP8Vector() ||
21274 Subtarget.hasP10Vector())
21277 EVT VT =
Op->getValueType(0);
21278 if (!((SplatBitSize == 64 && VT == MVT::v2f64) ||
21279 (SplatBitSize == 32 && VT == MVT::v4f32)))
21286 APFloat APFloatVal = CN->getValueAPF();
21288 APSInt IntResult(16,
false);
21291 if (!(IsExact && IntResult <= 15 && IntResult >= -16 && !APFloatVal.
isZero()))
21294 int64_t
IntVal = IntResult.getSExtValue();
21299 if (SplatBitSize == 64)
21302 DAG.
getConstant(Intrinsic::ppc_vsx_xvcvsxwdp, dl, MVT::i32), IntSplat);
21304 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()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
MCRegister getGlueCodeDescriptorRegister() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool isJumpTableRelative() const override
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node, in exactly one operand.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
bool willNotOverflowSub(bool IsSigned, SDValue N0, SDValue N1) const
Determine if the result of the sub of 2 nodes can never overflow.
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI bool isKnownNeverZero(SDValue Op, unsigned Depth=0) const
Test whether the given SDValue is known to contain non-zero value(s).
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setPartialReduceMLAAction(unsigned Opc, MVT AccVT, MVT InputVT, LegalizeAction Action)
Indicate how a PARTIAL_REDUCE_U/SMLA node with Acc type AccVT and Input type InputVT should be treate...
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode, SDNodeFlags Flags={}) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual TargetLoweringObjectFile * getObjFileLowering() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
bool getFunctionSections() const
Return true if functions should be emitted into their own section, corresponding to -ffunction-sectio...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering)
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
RelativeUniformCounterPtr Values
@ Known
Known to have no common set bits.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr RegState getDefRegState(bool B)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
LLVM_ABI bool isOneOrOneSplat(SDValue V, bool AllowUndefs=false)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const unsigned PerfectShuffleTable[6561+1]
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
@ Fast
Assign the register banks as fast as possible (default).
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
LLVM_ABI bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool bitsLT(EVT VT) const
Return true if this has less bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.