69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
149 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
153 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
154 "function to use initial-exec"));
159 "Number of shuffles lowered to a VPERM or XXPERM");
160STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
181 initializeAddrModeMap();
184 bool isPPC64 = Subtarget.isPPC64();
186 const MVT RegVT = Subtarget.getScalarIntVT();
194 if (!Subtarget.hasEFPU2())
211 if (!Subtarget.hasP10Vector()) {
240 if (Subtarget.isISA3_0()) {
273 if (!Subtarget.hasSPE()) {
280 if (Subtarget.useCRBits()) {
283 if (isPPC64 || Subtarget.hasFPCVT()) {
349 if (Subtarget.isISA3_0()) {
384 if (!Subtarget.hasSPE()) {
389 if (Subtarget.hasVSX()) {
394 if (Subtarget.hasFSQRT()) {
399 if (Subtarget.hasFPRND()) {
440 if (Subtarget.hasSPE()) {
450 if (Subtarget.hasSPE())
454 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
457 if (!Subtarget.hasFSQRT() &&
458 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
461 if (Subtarget.hasFCPSGN()) {
469 if (Subtarget.hasFPRND()) {
483 if (Subtarget.isISA3_1()) {
489 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
493 if (Subtarget.isISA3_0()) {
513 if (!Subtarget.useCRBits()) {
526 if (!Subtarget.useCRBits())
529 if (Subtarget.hasFPU()) {
540 if (!Subtarget.useCRBits())
545 if (Subtarget.hasSPE()) {
569 if (Subtarget.hasDirectMove() && isPPC64) {
629 if (Subtarget.is64BitELFABI()) {
640 }
else if (Subtarget.is32BitELFABI()) {
648 if (Subtarget.is32BitELFABI())
664 if (Subtarget.isISA3_0() && isPPC64) {
692 if (Subtarget.hasSPE()) {
714 if (Subtarget.has64BitSupport()) {
729 if (Subtarget.hasLFIWAX() || isPPC64) {
735 if (Subtarget.hasSPE()) {
745 if (Subtarget.hasFPCVT()) {
746 if (Subtarget.has64BitSupport()) {
767 if (Subtarget.use64BitRegs()) {
785 if (Subtarget.has64BitSupport()) {
792 if (Subtarget.hasVSX()) {
805 if (Subtarget.hasAltivec()) {
806 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
823 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
836 if (Subtarget.hasVSX()) {
845 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
855 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
929 if (!Subtarget.hasP8Vector()) {
971 if (Subtarget.hasAltivec())
972 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
975 if (Subtarget.hasP8Altivec())
986 if (Subtarget.hasVSX()) {
992 if (Subtarget.hasP8Altivec())
997 if (Subtarget.isISA3_1()) {
1043 if (Subtarget.hasVSX()) {
1046 if (Subtarget.hasP8Vector()) {
1050 if (Subtarget.hasDirectMove() && isPPC64) {
1099 if (Subtarget.hasP8Vector())
1108 if (Subtarget.hasP8Altivec()) {
1135 if (Subtarget.isISA3_1())
1238 if (Subtarget.hasP8Altivec()) {
1243 if (Subtarget.hasP9Vector()) {
1248 if (Subtarget.useCRBits()) {
1308 }
else if (Subtarget.hasVSX()) {
1333 for (
MVT VT : {MVT::f32, MVT::f64}) {
1352 if (Subtarget.hasP9Altivec()) {
1353 if (Subtarget.isISA3_1()) {
1376 if (Subtarget.hasP10Vector()) {
1381 if (Subtarget.pairedVectorMemops()) {
1386 if (Subtarget.hasMMA()) {
1387 if (Subtarget.isISAFuture()) {
1403 if (Subtarget.has64BitSupport())
1406 if (Subtarget.isISA3_1())
1424 if (Subtarget.hasAltivec()) {
1442 if (Subtarget.hasFPCVT())
1445 if (Subtarget.useCRBits())
1454 if (Subtarget.useCRBits()) {
1458 if (Subtarget.hasP8Vector())
1463 if (Subtarget.useCRBits()) {
1479 auto CPUDirective = Subtarget.getCPUDirective();
1480 switch (CPUDirective) {
1503 if (Subtarget.enableMachineScheduler())
1577void PPCTargetLowering::initializeAddrModeMap() {
1628 if (MaxAlign == MaxMaxAlign)
1631 if (MaxMaxAlign >= 32 &&
1632 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1633 MaxAlign =
Align(32);
1634 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1636 MaxAlign =
Align(16);
1640 if (EltAlign > MaxAlign)
1641 MaxAlign = EltAlign;
1643 for (
auto *EltTy : STy->elements()) {
1646 if (EltAlign > MaxAlign)
1647 MaxAlign = EltAlign;
1648 if (MaxAlign == MaxMaxAlign)
1661 if (Subtarget.hasAltivec())
1667 return Subtarget.useSoftFloat();
1671 return Subtarget.hasSPE();
1679 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1680 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1684 if (VTy->getScalarType()->isIntegerTy()) {
1686 if (ElemSizeInBits == 32) {
1687 Index = Subtarget.isLittleEndian() ? 2 : 1;
1690 if (ElemSizeInBits == 64) {
1691 Index = Subtarget.isLittleEndian() ? 1 : 0;
1702 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1719 return CFP->getValueAPF().isZero();
1724 return CFP->getValueAPF().isZero();
1732 return Op < 0 ||
Op == Val;
1744 if (ShuffleKind == 0) {
1747 for (
unsigned i = 0; i != 16; ++i)
1750 }
else if (ShuffleKind == 2) {
1753 for (
unsigned i = 0; i != 16; ++i)
1756 }
else if (ShuffleKind == 1) {
1757 unsigned j = IsLE ? 0 : 1;
1758 for (
unsigned i = 0; i != 8; ++i)
1775 if (ShuffleKind == 0) {
1778 for (
unsigned i = 0; i != 16; i += 2)
1782 }
else if (ShuffleKind == 2) {
1785 for (
unsigned i = 0; i != 16; i += 2)
1789 }
else if (ShuffleKind == 1) {
1790 unsigned j = IsLE ? 0 : 2;
1791 for (
unsigned i = 0; i != 8; i += 2)
1812 if (!Subtarget.hasP8Vector())
1816 if (ShuffleKind == 0) {
1819 for (
unsigned i = 0; i != 16; i += 4)
1825 }
else if (ShuffleKind == 2) {
1828 for (
unsigned i = 0; i != 16; i += 4)
1834 }
else if (ShuffleKind == 1) {
1835 unsigned j = IsLE ? 0 : 4;
1836 for (
unsigned i = 0; i != 8; i += 4)
1853 unsigned LHSStart,
unsigned RHSStart) {
1854 if (
N->getValueType(0) != MVT::v16i8)
1856 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1857 "Unsupported merge size!");
1859 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1860 for (
unsigned j = 0; j != UnitSize; ++j) {
1862 LHSStart+j+i*UnitSize) ||
1864 RHSStart+j+i*UnitSize))
1879 if (ShuffleKind == 1)
1881 else if (ShuffleKind == 2)
1886 if (ShuffleKind == 1)
1888 else if (ShuffleKind == 0)
1904 if (ShuffleKind == 1)
1906 else if (ShuffleKind == 2)
1911 if (ShuffleKind == 1)
1913 else if (ShuffleKind == 0)
1963 unsigned RHSStartValue) {
1964 if (
N->getValueType(0) != MVT::v16i8)
1967 for (
unsigned i = 0; i < 2; ++i)
1968 for (
unsigned j = 0; j < 4; ++j)
1970 i*RHSStartValue+j+IndexOffset) ||
1972 i*RHSStartValue+j+IndexOffset+8))
1994 unsigned indexOffset = CheckEven ? 4 : 0;
1995 if (ShuffleKind == 1)
1997 else if (ShuffleKind == 2)
2003 unsigned indexOffset = CheckEven ? 0 : 4;
2004 if (ShuffleKind == 1)
2006 else if (ShuffleKind == 0)
2022 if (
N->getValueType(0) != MVT::v16i8)
2029 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2032 if (i == 16)
return -1;
2037 if (ShiftAmt < i)
return -1;
2042 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2044 for (++i; i != 16; ++i)
2047 }
else if (ShuffleKind == 1) {
2049 for (++i; i != 16; ++i)
2056 ShiftAmt = 16 - ShiftAmt;
2065 EVT VT =
N->getValueType(0);
2066 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2067 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2070 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2074 if (
N->getMaskElt(0) % EltSize != 0)
2079 unsigned ElementBase =
N->getMaskElt(0);
2082 if (ElementBase >= 16)
2087 for (
unsigned i = 1; i != EltSize; ++i)
2088 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2091 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2093 if (
N->getMaskElt(i) < 0) {
2094 for (
unsigned j = 1; j != EltSize; ++j)
2095 if (
N->getMaskElt(i + j) >= 0)
2098 for (
unsigned j = 0; j != EltSize; ++j)
2099 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2116 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2117 "Unexpected element width.");
2118 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2120 unsigned NumOfElem = 16 / Width;
2121 unsigned MaskVal[16];
2122 for (
unsigned i = 0; i < NumOfElem; ++i) {
2123 MaskVal[0] =
N->getMaskElt(i * Width);
2124 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2126 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2130 for (
unsigned int j = 1; j < Width; ++j) {
2131 MaskVal[j] =
N->getMaskElt(i * Width + j);
2132 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2142 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2147 unsigned M0 =
N->getMaskElt(0) / 4;
2148 unsigned M1 =
N->getMaskElt(4) / 4;
2149 unsigned M2 =
N->getMaskElt(8) / 4;
2150 unsigned M3 =
N->getMaskElt(12) / 4;
2151 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2152 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2157 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2158 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2159 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2160 InsertAtByte = IsLE ? 12 : 0;
2165 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2166 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2167 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2168 InsertAtByte = IsLE ? 8 : 4;
2173 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2174 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2175 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2176 InsertAtByte = IsLE ? 4 : 8;
2181 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2182 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2183 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2184 InsertAtByte = IsLE ? 0 : 12;
2191 if (
N->getOperand(1).isUndef()) {
2194 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2195 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2196 InsertAtByte = IsLE ? 12 : 0;
2199 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2200 InsertAtByte = IsLE ? 8 : 4;
2203 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2204 InsertAtByte = IsLE ? 4 : 8;
2207 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2208 InsertAtByte = IsLE ? 0 : 12;
2217 bool &Swap,
bool IsLE) {
2218 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2224 unsigned M0 =
N->getMaskElt(0) / 4;
2225 unsigned M1 =
N->getMaskElt(4) / 4;
2226 unsigned M2 =
N->getMaskElt(8) / 4;
2227 unsigned M3 =
N->getMaskElt(12) / 4;
2231 if (
N->getOperand(1).isUndef()) {
2232 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2233 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2236 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2242 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2246 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2251 ShiftElts = (8 -
M0) % 8;
2252 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2257 ShiftElts = (4 -
M0) % 4;
2262 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2267 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2279 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2284 for (
int i = 0; i < 16; i += Width)
2285 if (
N->getMaskElt(i) != i + Width - 1)
2316 bool &Swap,
bool IsLE) {
2317 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2323 unsigned M0 =
N->getMaskElt(0) / 8;
2324 unsigned M1 =
N->getMaskElt(8) / 8;
2325 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2329 if (
N->getOperand(1).isUndef()) {
2330 if ((
M0 |
M1) < 2) {
2331 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2339 if (
M0 > 1 &&
M1 < 2) {
2349 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2354 }
else if (
M0 > 1 &&
M1 < 2) {
2362 DM = (
M0 << 1) + (
M1 & 1);
2377 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2382 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2398 unsigned EltSize = 16/
N->getNumOperands();
2399 if (EltSize < ByteSize) {
2400 unsigned Multiple = ByteSize/EltSize;
2402 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2405 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2406 if (
N->getOperand(i).isUndef())
continue;
2410 if (!UniquedVals[i&(Multiple-1)].
getNode())
2411 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2412 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2422 bool LeadingZero =
true;
2423 bool LeadingOnes =
true;
2424 for (
unsigned i = 0; i != Multiple-1; ++i) {
2425 if (!UniquedVals[i].
getNode())
continue;
2432 if (!UniquedVals[Multiple-1].
getNode())
2439 if (!UniquedVals[Multiple-1].
getNode())
2450 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2451 if (
N->getOperand(i).isUndef())
continue;
2453 OpVal =
N->getOperand(i);
2454 else if (OpVal !=
N->getOperand(i))
2460 unsigned ValSizeInBytes = EltSize;
2463 Value = CN->getZExtValue();
2465 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2472 if (ValSizeInBytes < ByteSize)
return SDValue();
2483 if (MaskVal == 0)
return SDValue();
2503 Imm = (int16_t)
N->getAsZExtVal();
2504 if (
N->getValueType(0) == MVT::i32)
2505 return Imm == (int32_t)
N->getAsZExtVal();
2507 return Imm == (int64_t)
N->getAsZExtVal();
2525 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2533 for (
SDNode *U :
N->users()) {
2535 if (Memop->getMemoryVT() == MVT::f64) {
2536 Base =
N.getOperand(0);
2537 Index =
N.getOperand(1);
2580 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2582 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2585 Base =
N.getOperand(0);
2586 Index =
N.getOperand(1);
2588 }
else if (
N.getOpcode() ==
ISD::OR) {
2590 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2602 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2603 Base =
N.getOperand(0);
2604 Index =
N.getOperand(1);
2674 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2680 Base =
N.getOperand(0);
2683 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2685 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2686 "Cannot handle constant offsets yet!");
2687 Disp =
N.getOperand(1).getOperand(0);
2692 Base =
N.getOperand(0);
2695 }
else if (
N.getOpcode() ==
ISD::OR) {
2698 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2712 Base =
N.getOperand(0);
2725 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2728 CN->getValueType(0));
2733 if ((CN->getValueType(0) == MVT::i32 ||
2734 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2735 (!EncodingAlignment ||
2736 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2737 int Addr = (int)CN->getZExtValue();
2744 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2765 if (
N.getValueType() != MVT::i64)
2778 Base =
N.getOperand(0);
2794 Base =
N.getOperand(0);
2827 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2828 Base =
N.getOperand(0);
2829 Index =
N.getOperand(1);
2851 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2872 EVT MemVT = LD->getMemoryVT();
2879 if (!ST.hasP8Vector())
2884 if (!ST.hasP9Vector())
2896 if (
Use.getResNo() == 0 &&
2898 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2918 Ptr = LD->getBasePtr();
2919 VT = LD->getMemoryVT();
2920 Alignment = LD->getAlign();
2922 Ptr = ST->getBasePtr();
2923 VT = ST->getMemoryVT();
2924 Alignment = ST->getAlign();
2963 if (VT != MVT::i64) {
2968 if (Alignment <
Align(4))
2978 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
2995 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3037 EVT VT = Subtarget.getScalarIntVT();
3039 : Subtarget.isAIXABI()
3044 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3051 EVT PtrVT =
Op.getValueType();
3057 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3058 if (Subtarget.isUsingPCRelativeCalls()) {
3063 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3067 return getTOCEntry(DAG, SDLoc(CP), GA);
3070 unsigned MOHiFlag, MOLoFlag;
3074 if (IsPIC && Subtarget.isSVR4ABI()) {
3077 return getTOCEntry(DAG, SDLoc(CP), GA);
3100 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3107 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3124 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3137 EVT PtrVT =
Op.getValueType();
3155 return getTOCEntry(DAG,
SDLoc(JT), GA);
3158 unsigned MOHiFlag, MOLoFlag;
3162 if (IsPIC && Subtarget.isSVR4ABI()) {
3165 return getTOCEntry(DAG, SDLoc(GA), GA);
3175 EVT PtrVT =
Op.getValueType();
3180 if (Subtarget.isUsingPCRelativeCalls()) {
3191 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3194 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3203 unsigned MOHiFlag, MOLoFlag;
3213 if (Subtarget.isAIXABI())
3214 return LowerGlobalTLSAddressAIX(
Op, DAG);
3216 return LowerGlobalTLSAddressLinux(
Op, DAG);
3238 if (
I.getOpcode() == Instruction::Call)
3240 if (
Function *CF = CI->getCalledFunction())
3241 if (CF->isDeclaration() &&
3242 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3250 unsigned TLSGVCnt = TLSGV.
size();
3260 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3273 const GlobalValue *GV = GA->
getGlobal();
3275 bool Is64Bit = Subtarget.isPPC64();
3279 if (Subtarget.hasAIXShLibTLSModelOpt())
3289 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3290 bool HasAIXSmallTLSGlobalAttr =
false;
3293 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3297 if (GVar->hasAttribute(
"aix-small-tls"))
3298 HasAIXSmallTLSGlobalAttr =
true;
3317 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3318 IsTLSLocalExecModel) {
3323 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3333 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3338 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3340 "currently only supported on AIX (64-bit mode).");
3342 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3346 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3350 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3352 "currently only supported on AIX (64-bit mode).");
3360 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3363 GlobalVariable *TLSGV =
3367 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3370 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3372 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3381 if (HasAIXSmallLocalDynamicTLS) {
3386 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3390 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3403 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3404 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3405 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3420 const GlobalValue *GV = GA->
getGlobal();
3422 bool is64bit = Subtarget.isPPC64();
3430 if (Subtarget.isUsingPCRelativeCalls()) {
3435 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3436 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3447 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3451 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3458 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3460 MachinePointerInfo());
3467 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3469 if (!TM.isPositionIndependent())
3470 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3476 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3478 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3482 if (Subtarget.isUsingPCRelativeCalls()) {
3485 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3493 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3501 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3506 if (Subtarget.isUsingPCRelativeCalls()) {
3510 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3511 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3519 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3528 PtrVT, GOTPtr, TGA, TGA);
3530 PtrVT, TLSAddr, TGA);
3531 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3539 EVT PtrVT =
Op.getValueType();
3542 const GlobalValue *GV = GSDN->
getGlobal();
3546 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3547 if (Subtarget.isUsingPCRelativeCalls()) {
3554 MachinePointerInfo());
3559 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3564 return getTOCEntry(DAG,
DL, GA);
3567 unsigned MOHiFlag, MOLoFlag;
3571 if (IsPIC && Subtarget.isSVR4ABI()) {
3575 return getTOCEntry(DAG,
DL, GA);
3587 bool IsStrict =
Op->isStrictFPOpcode();
3593 EVT LHSVT =
LHS.getValueType();
3597 if (LHSVT == MVT::f128) {
3598 assert(!Subtarget.hasP9Vector() &&
3599 "SETCC for f128 is already legal under Power9!");
3610 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3612 if (
Op.getValueType() == MVT::v2i64) {
3615 if (
LHS.getValueType() == MVT::v2i64) {
3623 int ShuffV[] = {1, 0, 3, 2};
3628 dl, MVT::v4i32, Shuff, SetCC32));
3645 if (
C->isAllOnes() ||
C->isZero())
3655 EVT VT =
Op.getValueType();
3663 SDNode *
Node =
Op.getNode();
3664 EVT VT =
Node->getValueType(0);
3671 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3675 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3678 if (VT == MVT::i64) {
3697 FprPtr, MachinePointerInfo(SV), MVT::i8);
3708 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3709 InChain = OverflowArea.
getValue(1);
3712 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3742 MachinePointerInfo(SV), MVT::i8);
3755 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3756 MachinePointerInfo(), MVT::i32);
3758 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3762 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3768 false,
true,
nullptr, std::nullopt,
3769 MachinePointerInfo(), MachinePointerInfo());
3774 return Op.getOperand(0);
3779 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3783 "Expecting Inline ASM node.");
3793 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3798 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3799 unsigned NumVals =
Flags.getNumOperandRegisters();
3802 switch (
Flags.getKind()) {
3813 for (; NumVals; --NumVals, ++i) {
3815 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3838 if (Subtarget.isAIXABI()) {
3842 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3843 MaybeAlign PointerAlign(PointerSize);
3844 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3847 : MachineMemOperand::MONone;
3854 const Value *TrampolineAddr =
3864 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3865 PointerAlign, MMOFlags);
3867 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3868 MachinePointerInfo(TrampolineAddr, 0));
3872 SDValue TOCFromDescriptorPtr =
3874 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3875 MachinePointerInfo(Func, TOCPointerOffset),
3876 PointerAlign, MMOFlags);
3877 SDValue TrampolineTOCPointer =
3881 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3882 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3888 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3889 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3896 bool isPPC64 = (PtrVT == MVT::i64);
3900 Args.emplace_back(Trmp, IntPtrTy);
3903 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3905 Args.emplace_back(FPtr, IntPtrTy);
3906 Args.emplace_back(Nest, IntPtrTy);
3909 TargetLowering::CallLoweringInfo CLI(DAG);
3910 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3914 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3915 return CallResult.second;
3920 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3925 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3930 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3931 MachinePointerInfo(SV));
3965 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3968 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3971 uint64_t FPROffset = 1;
3979 MachinePointerInfo(SV), MVT::i8);
3980 uint64_t nextOffset = FPROffset;
3987 MachinePointerInfo(SV, nextOffset), MVT::i8);
3988 nextOffset += StackOffset;
3989 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3992 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3993 MachinePointerInfo(SV, nextOffset));
3994 nextOffset += FrameOffset;
3995 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3998 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3999 MachinePointerInfo(SV, nextOffset));
4004static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4005 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4006 PPC::F11, PPC::F12, PPC::F13};
4011 unsigned PtrByteSize) {
4013 if (Flags.isByVal())
4014 ArgSize = Flags.getByValSize();
4018 if (!Flags.isInConsecutiveRegs())
4019 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4028 unsigned PtrByteSize) {
4029 Align Alignment(PtrByteSize);
4032 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4033 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4034 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4035 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4036 Alignment =
Align(16);
4039 if (Flags.isByVal()) {
4040 auto BVAlign = Flags.getNonZeroByValAlign();
4041 if (BVAlign > PtrByteSize) {
4042 if (BVAlign.value() % PtrByteSize != 0)
4044 "ByVal alignment is not a multiple of the pointer size");
4046 Alignment = BVAlign;
4051 if (Flags.isInConsecutiveRegs()) {
4055 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4069 unsigned PtrByteSize,
unsigned LinkageSize,
4070 unsigned ParamAreaSize,
unsigned &ArgOffset,
4071 unsigned &AvailableFPRs,
4072 unsigned &AvailableVRs) {
4073 bool UseMemory =
false;
4078 ArgOffset =
alignTo(ArgOffset, Alignment);
4081 if (ArgOffset >= LinkageSize + ParamAreaSize)
4086 if (Flags.isInConsecutiveRegsLast())
4087 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4090 if (ArgOffset > LinkageSize + ParamAreaSize)
4095 if (!Flags.isByVal()) {
4096 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4097 if (AvailableFPRs > 0) {
4101 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4102 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4103 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4104 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4105 if (AvailableVRs > 0) {
4117 unsigned NumBytes) {
4121SDValue PPCTargetLowering::LowerFormalArguments(
4125 if (Subtarget.isAIXABI())
4126 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4128 if (Subtarget.is64BitELFABI())
4129 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4131 assert(Subtarget.is32BitELFABI());
4132 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4136SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4172 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4178 const Align PtrAlign(4);
4186 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4187 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4190 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4191 CCValAssign &VA = ArgLocs[i];
4195 const TargetRegisterClass *RC;
4203 RC = &PPC::GPRCRegClass;
4206 if (Subtarget.hasP8Vector())
4207 RC = &PPC::VSSRCRegClass;
4208 else if (Subtarget.hasSPE())
4209 RC = &PPC::GPRCRegClass;
4211 RC = &PPC::F4RCRegClass;
4214 if (Subtarget.hasVSX())
4215 RC = &PPC::VSFRCRegClass;
4216 else if (Subtarget.hasSPE())
4218 RC = &PPC::GPRCRegClass;
4220 RC = &PPC::F8RCRegClass;
4225 RC = &PPC::VRRCRegClass;
4228 RC = &PPC::VRRCRegClass;
4232 RC = &PPC::VRRCRegClass;
4239 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4240 assert(i + 1 < e &&
"No second half of double precision argument");
4245 if (!Subtarget.isLittleEndian())
4247 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4252 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4253 if (ValVT == MVT::i1)
4268 ArgOffset += ArgSize - ObjSize;
4286 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4291 unsigned MinReservedArea = CCByValInfo.getStackSize();
4292 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4308 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4309 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4311 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4314 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4317 unsigned NumFPArgRegs = std::size(FPArgRegs);
4326 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4327 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4330 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4343 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4358 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4362 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4375 if (!MemOps.
empty())
4386 const SDLoc &dl)
const {
4390 else if (
Flags.isZExt())
4397SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4403 bool isELFv2ABI = Subtarget.isELFv2ABI();
4404 bool isLittleEndian = Subtarget.isLittleEndian();
4407 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4410 "fastcc not supported on varargs functions");
4416 unsigned PtrByteSize = 8;
4417 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4420 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4421 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4424 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4425 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4428 const unsigned Num_GPR_Regs = std::size(GPR);
4430 const unsigned Num_VR_Regs = std::size(VR);
4438 bool HasParameterArea = !isELFv2ABI || isVarArg;
4439 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4440 unsigned NumBytes = LinkageSize;
4441 unsigned AvailableFPRs = Num_FPR_Regs;
4442 unsigned AvailableVRs = Num_VR_Regs;
4443 for (
const ISD::InputArg &In : Ins) {
4444 if (
In.Flags.isNest())
4448 LinkageSize, ParamAreaSize, NumBytes,
4449 AvailableFPRs, AvailableVRs))
4450 HasParameterArea =
true;
4457 unsigned ArgOffset = LinkageSize;
4458 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4461 unsigned CurArgIdx = 0;
4462 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4464 bool needsLoad =
false;
4465 EVT ObjectVT = Ins[ArgNo].VT;
4466 EVT OrigVT = Ins[ArgNo].ArgVT;
4468 unsigned ArgSize = ObjSize;
4469 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4470 if (Ins[ArgNo].isOrigArg()) {
4471 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4472 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4477 unsigned CurArgOffset;
4479 auto ComputeArgOffset = [&]() {
4483 ArgOffset =
alignTo(ArgOffset, Alignment);
4484 CurArgOffset = ArgOffset;
4491 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4492 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4497 if (
Flags.isByVal()) {
4498 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4504 ObjSize =
Flags.getByValSize();
4505 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4527 if (HasParameterArea ||
4528 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4535 if (ObjSize < PtrByteSize) {
4539 if (!isLittleEndian) {
4545 if (GPR_idx != Num_GPR_Regs) {
4552 MachinePointerInfo(&*FuncArg), ObjType);
4557 ArgOffset += PtrByteSize;
4566 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4567 if (GPR_idx == Num_GPR_Regs)
4578 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4582 MachinePointerInfo(&*FuncArg, j), ObjType);
4586 ArgOffset += ArgSize;
4595 if (
Flags.isNest()) {
4600 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4601 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4609 if (GPR_idx != Num_GPR_Regs) {
4614 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4617 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4623 ArgSize = PtrByteSize;
4634 if (FPR_idx != Num_FPR_Regs) {
4637 if (ObjectVT == MVT::f32)
4639 Subtarget.hasP8Vector()
4640 ? &PPC::VSSRCRegClass
4641 : &PPC::F4RCRegClass);
4644 ? &PPC::VSFRCRegClass
4645 : &PPC::F8RCRegClass);
4660 if (ObjectVT == MVT::f32) {
4661 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4679 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4680 ArgOffset += ArgSize;
4681 if (
Flags.isInConsecutiveRegsLast())
4682 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4696 if (VR_idx != Num_VR_Regs) {
4713 if (ObjSize < ArgSize && !isLittleEndian)
4714 CurArgOffset += ArgSize - ObjSize;
4717 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4724 unsigned MinReservedArea;
4725 if (HasParameterArea)
4726 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4728 MinReservedArea = LinkageSize;
4745 int Depth = ArgOffset;
4754 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4755 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4767 if (!MemOps.
empty())
4776 unsigned ParamSize) {
4778 if (!isTailCall)
return 0;
4782 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4784 if (SPDiff < FI->getTailCallSPDelta())
4800 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4859 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4862 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4874 const unsigned PtrByteSize = 8;
4878 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4879 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4882 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4883 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4886 const unsigned NumGPRs = std::size(GPR);
4887 const unsigned NumFPRs = 13;
4888 const unsigned NumVRs = std::size(VR);
4889 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4891 unsigned NumBytes = LinkageSize;
4892 unsigned AvailableFPRs = NumFPRs;
4893 unsigned AvailableVRs = NumVRs;
4896 if (Param.Flags.isNest())
continue;
4899 LinkageSize, ParamAreaSize, NumBytes,
4900 AvailableFPRs, AvailableVRs))
4911 auto CalleeArgEnd = CB.
arg_end();
4914 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4915 const Value* CalleeArg = *CalleeArgIter;
4916 const Value* CallerArg = &(*CallerArgIter);
4917 if (CalleeArg == CallerArg)
4943 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4953bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4958 bool isCalleeExternalSymbol)
const {
4961 if (
DisableSCO && !TailCallOpt)
return false;
4964 if (isVarArg)
return false;
4971 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5007 if (!Subtarget.isUsingPCRelativeCalls() &&
5012 if (!Subtarget.isUsingPCRelativeCalls() &&
5040bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5053 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5074 if (!
C)
return nullptr;
5076 int Addr =
C->getZExtValue();
5077 if ((Addr & 3) != 0 ||
5083 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5090struct TailCallArgumentInfo {
5095 TailCallArgumentInfo() =
default;
5105 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5106 SDValue Arg = TailCallArgs[i].Arg;
5107 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5108 int FI = TailCallArgs[i].FrameIdx;
5111 Chain, dl, Arg, FIN,
5120 int SPDiff,
const SDLoc &dl) {
5126 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5127 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5129 NewRetAddrLoc,
true);
5132 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5142 int SPDiff,
unsigned ArgOffset,
5144 int Offset = ArgOffset + SPDiff;
5147 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5149 TailCallArgumentInfo Info;
5151 Info.FrameIdxOp = FIN;
5159SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5164 LROpOut = getReturnAddrFrameIndex(DAG);
5165 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5166 MachinePointerInfo());
5183 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5191 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5215 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5225 if (!MemOpChains2.
empty())
5249SDValue PPCTargetLowering::LowerCallResult(
5257 CCRetInfo.AnalyzeCallResult(
5263 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5264 CCValAssign &VA = RVLocs[i];
5269 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5279 if (!Subtarget.isLittleEndian())
5281 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5347 bool IsStrictFPCall =
false) {
5349 return PPCISD::TC_RETURN;
5351 unsigned RetOpc = 0;
5366 RetOpc = PPCISD::CALL_NOTOC;
5381 RetOpc = PPCISD::CALL;
5382 if (IsStrictFPCall) {
5386 case PPCISD::BCTRL_LOAD_TOC:
5387 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5390 RetOpc = PPCISD::BCTRL_RM;
5392 case PPCISD::CALL_NOTOC:
5393 RetOpc = PPCISD::CALL_NOTOC_RM;
5396 RetOpc = PPCISD::CALL_RM;
5398 case PPCISD::CALL_NOP:
5399 RetOpc = PPCISD::CALL_NOP_RM;
5413 auto isLocalCallee = [&]() {
5429 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5445 return getAIXFuncEntryPointSymbolSDNode(GV);
5452 const char *SymName = S->getSymbol();
5459 return getAIXFuncEntryPointSymbolSDNode(
F);
5465 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5473 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5480 assert(Callee.getNode() &&
"What no callee?");
5486 "Expected a CALLSEQ_STARTSDNode.");
5503 SDValue MTCTROps[] = {Chain, Callee, Glue};
5504 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5505 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5545 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5564 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5565 Alignment, MMOFlags);
5572 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5579 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5591 "Nest parameter is not supported on AIX.");
5607 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5610 const bool IsPPC64 = Subtarget.isPPC64();
5615 Ops.push_back(Chain);
5619 Ops.push_back(Callee);
5639 Ops.push_back(AddTOC);
5650 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5659 for (
const auto &[
Reg,
N] : RegsToPass)
5677 assert(Mask &&
"Missing call preserved mask for calling convention");
5682 Ops.push_back(Glue);
5685SDValue PPCTargetLowering::FinishCall(
5692 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5693 Subtarget.isAIXABI())
5700 if (!CFlags.IsIndirect)
5702 else if (Subtarget.usesFunctionDescriptors())
5704 dl, CFlags.HasNest, Subtarget);
5714 if (CFlags.IsTailCall) {
5722 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5723 "Expecting a global address, external symbol, absolute value, "
5724 "register or an indirect tail call when PC Relative calls are "
5727 assert(CallOpc == PPCISD::TC_RETURN &&
5728 "Unexpected call opcode for a tail call.");
5735 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5736 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5748 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5751 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5771 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5772 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5776bool PPCTargetLowering::isEligibleForTCO(
5781 bool isCalleeExternalSymbol)
const {
5785 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5786 return IsEligibleForTailCallOptimization_64SVR4(
5787 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5788 isCalleeExternalSymbol);
5790 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5818 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5833 "Callee should be an llvm::Function object.");
5836 <<
"\nTCO callee: ");
5843 "site marked musttail");
5850 Callee = LowerGlobalAddress(Callee, DAG);
5853 CallConv, isTailCall, isVarArg, isPatchPoint,
5856 Subtarget.is64BitELFABI() &&
5860 if (Subtarget.isAIXABI())
5861 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5864 assert(Subtarget.isSVR4ABI());
5865 if (Subtarget.isPPC64())
5866 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5868 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5872SDValue PPCTargetLowering::LowerCall_32SVR4(
5883 const bool IsVarArg = CFlags.IsVarArg;
5884 const bool IsTailCall = CFlags.IsTailCall;
5890 const Align PtrAlign(4);
5901 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5909 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5912 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5919 unsigned NumArgs = Outs.
size();
5921 for (
unsigned i = 0; i != NumArgs; ++i) {
5922 MVT ArgVT = Outs[i].VT;
5923 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5928 Outs[i].OrigTy, CCInfo);
5931 ArgFlags, Outs[i].OrigTy, CCInfo);
5936 errs() <<
"Call operand #" << i <<
" has unhandled type "
5949 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
5952 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5959 unsigned NumBytes = CCByValInfo.getStackSize();
5973 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5984 bool seenFloatArg =
false;
5989 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5991 ++i, ++RealArgIdx) {
5992 CCValAssign &VA = ArgLocs[i];
5993 SDValue Arg = OutVals[RealArgIdx];
5994 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
5996 if (
Flags.isByVal()) {
6001 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6002 CCValAssign &ByValVA = ByValArgLocs[
j++];
6024 Chain = CallSeqStart = NewCallSeqStart;
6043 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6044 bool IsLE = Subtarget.isLittleEndian();
6045 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6048 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6050 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6065 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6074 if (!MemOpChains.
empty())
6080 for (
const auto &[
Reg,
N] : RegsToPass) {
6088 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6091 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6101 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6102 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6107SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6119 return NewCallSeqStart;
6122SDValue PPCTargetLowering::LowerCall_64SVR4(
6129 bool isELFv2ABI = Subtarget.isELFv2ABI();
6130 bool isLittleEndian = Subtarget.isLittleEndian();
6132 bool IsSibCall =
false;
6136 unsigned PtrByteSize = 8;
6149 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6151 assert(!(IsFastCall && CFlags.IsVarArg) &&
6152 "fastcc not supported on varargs functions");
6158 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6159 unsigned NumBytes = LinkageSize;
6160 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6163 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6164 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6167 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6168 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6171 const unsigned NumGPRs = std::size(GPR);
6173 const unsigned NumVRs = std::size(VR);
6179 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6180 if (!HasParameterArea) {
6181 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6182 unsigned AvailableFPRs = NumFPRs;
6183 unsigned AvailableVRs = NumVRs;
6184 unsigned NumBytesTmp = NumBytes;
6185 for (
unsigned i = 0; i !=
NumOps; ++i) {
6186 if (Outs[i].
Flags.isNest())
continue;
6188 PtrByteSize, LinkageSize, ParamAreaSize,
6189 NumBytesTmp, AvailableFPRs, AvailableVRs))
6190 HasParameterArea =
true;
6196 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6201 HasParameterArea =
false;
6204 for (
unsigned i = 0; i !=
NumOps; ++i) {
6205 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6206 EVT ArgVT = Outs[i].VT;
6207 EVT OrigVT = Outs[i].ArgVT;
6213 if (
Flags.isByVal()) {
6214 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6215 if (NumGPRsUsed > NumGPRs)
6216 HasParameterArea =
true;
6223 if (++NumGPRsUsed <= NumGPRs)
6233 if (++NumVRsUsed <= NumVRs)
6237 if (++NumVRsUsed <= NumVRs)
6242 if (++NumFPRsUsed <= NumFPRs)
6246 HasParameterArea =
true;
6253 NumBytes =
alignTo(NumBytes, Alignement);
6256 if (
Flags.isInConsecutiveRegsLast())
6257 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6260 unsigned NumBytesActuallyUsed = NumBytes;
6270 if (HasParameterArea)
6271 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6273 NumBytes = LinkageSize;
6288 if (CFlags.IsTailCall)
6300 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6311 unsigned ArgOffset = LinkageSize;
6317 for (
unsigned i = 0; i !=
NumOps; ++i) {
6319 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6320 EVT ArgVT = Outs[i].VT;
6321 EVT OrigVT = Outs[i].ArgVT;
6330 auto ComputePtrOff = [&]() {
6334 ArgOffset =
alignTo(ArgOffset, Alignment);
6345 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6346 GPR_idx = std::min(GPR_idx, NumGPRs);
6353 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6359 if (
Flags.isByVal()) {
6377 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6378 if (GPR_idx != NumGPRs) {
6380 MachinePointerInfo(), VT);
6382 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6384 ArgOffset += PtrByteSize;
6389 if (GPR_idx == NumGPRs &&
Size < 8) {
6391 if (!isLittleEndian) {
6396 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6399 ArgOffset += PtrByteSize;
6408 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6409 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6414 if (
Size < 8 && GPR_idx != NumGPRs) {
6424 if (!isLittleEndian) {
6428 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6434 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6436 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6439 ArgOffset += PtrByteSize;
6445 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6448 if (GPR_idx != NumGPRs) {
6449 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6452 MachinePointerInfo(), ObjType);
6455 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6456 ArgOffset += PtrByteSize;
6458 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6470 if (
Flags.isNest()) {
6472 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6479 if (GPR_idx != NumGPRs) {
6480 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6485 assert(HasParameterArea &&
6486 "Parameter area must exist to pass an argument in memory.");
6488 true, CFlags.IsTailCall,
false, MemOpChains,
6489 TailCallArguments, dl);
6491 ArgOffset += PtrByteSize;
6494 ArgOffset += PtrByteSize;
6507 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6508 bool NeededLoad =
false;
6511 if (FPR_idx != NumFPRs)
6512 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6515 if (!NeedGPROrStack)
6517 else if (GPR_idx != NumGPRs && !IsFastCall) {
6531 }
else if (!
Flags.isInConsecutiveRegs()) {
6537 }
else if (ArgOffset % PtrByteSize != 0) {
6541 if (!isLittleEndian)
6546 }
else if (
Flags.isInConsecutiveRegsLast()) {
6549 if (!isLittleEndian)
6559 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6567 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6572 assert(HasParameterArea &&
6573 "Parameter area must exist to pass an argument in memory.");
6575 true, CFlags.IsTailCall,
false, MemOpChains,
6576 TailCallArguments, dl);
6583 if (!IsFastCall || NeededLoad) {
6585 Flags.isInConsecutiveRegs()) ? 4 : 8;
6586 if (
Flags.isInConsecutiveRegsLast())
6587 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6607 if (CFlags.IsVarArg) {
6608 assert(HasParameterArea &&
6609 "Parameter area must exist if we have a varargs call.");
6613 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6615 if (VR_idx != NumVRs) {
6617 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6619 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6622 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6623 if (GPR_idx == NumGPRs)
6628 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6630 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6636 if (VR_idx != NumVRs) {
6637 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6642 assert(HasParameterArea &&
6643 "Parameter area must exist to pass an argument in memory.");
6645 true, CFlags.IsTailCall,
true, MemOpChains,
6646 TailCallArguments, dl);
6657 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6658 "mismatch in size of parameter area");
6659 (void)NumBytesActuallyUsed;
6661 if (!MemOpChains.
empty())
6667 if (CFlags.IsIndirect) {
6671 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6676 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6686 if (isELFv2ABI && !CFlags.IsPatchPoint)
6687 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6693 for (
const auto &[
Reg,
N] : RegsToPass) {
6698 if (CFlags.IsTailCall && !IsSibCall)
6702 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6703 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6710 "Required alignment greater than stack alignment.");
6730 return RequiredAlign <= 8;
6735 return RequiredAlign <= 4;
6743 State.getMachineFunction().getSubtarget());
6744 const bool IsPPC64 = Subtarget.isPPC64();
6745 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6746 const Align PtrAlign(PtrSize);
6747 const Align StackAlign(16);
6750 if (ValVT == MVT::f128)
6754 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6755 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6757 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6758 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6761 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6762 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6763 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6768 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6777 if (ByValAlign > StackAlign)
6779 "16 are not supported.");
6782 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6786 if (ByValSize == 0) {
6788 State.getStackSize(), RegVT, LocInfo));
6793 unsigned NextReg = State.getFirstUnallocated(GPRs);
6794 while (NextReg != GPRs.
size() &&
6799 State.AllocateStack(PtrSize, PtrAlign);
6800 assert(
Reg &&
"Alocating register unexpectedly failed.");
6802 NextReg = State.getFirstUnallocated(GPRs);
6805 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6806 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6826 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6830 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6849 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6855 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6857 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6858 if (State.isVarArg()) {
6890 const unsigned VecSize = 16;
6891 const Align VecAlign(VecSize);
6893 if (!State.isVarArg()) {
6896 if (
MCRegister VReg = State.AllocateReg(VR)) {
6903 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6908 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6911 while (NextRegIndex != GPRs.
size() &&
6915 State.AllocateStack(PtrSize, PtrAlign);
6916 assert(
Reg &&
"Allocating register unexpectedly failed.");
6918 NextRegIndex = State.getFirstUnallocated(GPRs);
6926 if (
MCRegister VReg = State.AllocateReg(VR)) {
6929 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6930 State.AllocateReg(GPRs);
6931 State.AllocateStack(VecSize, VecAlign);
6935 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6941 if (NextRegIndex == GPRs.
size()) {
6942 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6950 if (GPRs[NextRegIndex] == PPC::R9) {
6951 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6955 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
6956 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
6957 assert(FirstReg && SecondReg &&
6958 "Allocating R9 or R10 unexpectedly failed.");
6969 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6972 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6974 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
6989 assert((IsPPC64 || SVT != MVT::i64) &&
6990 "i64 should have been split for 32-bit codegen.");
6998 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7000 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7002 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7010 return &PPC::VRRCRegClass;
7023 else if (Flags.isZExt())
7035 "Reg must be a valid argument register!");
7036 return LASize + 4 * (
Reg - PPC::R3);
7041 "Reg must be a valid argument register!");
7042 return LASize + 8 * (
Reg - PPC::X3);
7088SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7095 "Unexpected calling convention!");
7103 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7105 const bool IsPPC64 = Subtarget.isPPC64();
7106 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7112 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7113 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7117 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7118 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7119 uint64_t SaveStackPos = CCInfo.getStackSize();
7121 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7125 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7126 CCValAssign &VA = ArgLocs[
I++];
7131 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7132 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7144 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7146 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7152 MachinePointerInfo(),
Align(PtrByteSize));
7158 unsigned StoreSize =
7160 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7163 auto HandleMemLoc = [&]() {
7166 assert((ValSize <= LocSize) &&
7167 "Object size is larger than size of MemLoc");
7170 if (LocSize > ValSize)
7171 CurArgOffset += LocSize - ValSize;
7173 const bool IsImmutable =
7179 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7213 assert(isVarArg &&
"Only use custom memloc for vararg.");
7216 const unsigned OriginalValNo = VA.
getValNo();
7217 (void)OriginalValNo;
7219 auto HandleCustomVecRegLoc = [&]() {
7220 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7221 "Missing custom RegLoc.");
7224 "Unexpected Val type for custom RegLoc.");
7226 "ValNo mismatch between custom MemLoc and RegLoc.");
7230 Subtarget.hasVSX()));
7237 HandleCustomVecRegLoc();
7238 HandleCustomVecRegLoc();
7242 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7244 "Only 2 custom RegLocs expected for 64-bit codegen.");
7245 HandleCustomVecRegLoc();
7246 HandleCustomVecRegLoc();
7290 const unsigned Size =
7302 if (
Flags.isByVal()) {
7306 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7308 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7316 const TargetRegisterClass *RegClass =
7317 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7319 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7332 CopyFrom.
getValue(1), dl, CopyFrom,
7342 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7345 "RegLocs should be for ByVal argument.");
7347 const CCValAssign RL = ArgLocs[
I++];
7352 if (
Offset != StackSize) {
7354 "Expected MemLoc for remaining bytes.");
7355 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7369 Subtarget.hasVSX()));
7386 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7388 unsigned CallerReservedArea = std::max<unsigned>(
7389 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7395 CallerReservedArea =
7400 int VAListIndex = 0;
7404 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7405 unsigned FixedStackSize =
7406 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7422 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7423 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7425 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7426 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7427 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7433 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7435 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7438 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7439 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7442 MachinePointerInfo MPI =
7452 if (!MemOps.
empty())
7458SDValue PPCTargetLowering::LowerCall_AIX(
7471 "Unexpected calling convention!");
7473 if (CFlags.IsPatchPoint)
7476 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7480 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7487 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7488 const bool IsPPC64 = Subtarget.isPPC64();
7490 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7491 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7492 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7500 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7501 const unsigned NumBytes = std::max<unsigned>(
7502 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7518 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7519 const unsigned ValNo = ArgLocs[
I].getValNo();
7521 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7523 if (
Flags.isByVal()) {
7524 const unsigned ByValSize =
Flags.getByValSize();
7532 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7538 MachinePointerInfo(), VT);
7541 unsigned LoadOffset = 0;
7544 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7547 LoadOffset += PtrByteSize;
7548 const CCValAssign &ByValVA = ArgLocs[
I++];
7550 "Unexpected location for pass-by-value argument.");
7554 if (LoadOffset == ByValSize)
7558 assert(ArgLocs[
I].getValNo() == ValNo &&
7559 "Expected additional location for by-value argument.");
7561 if (ArgLocs[
I].isMemLoc()) {
7562 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7563 const CCValAssign &ByValVA = ArgLocs[
I++];
7564 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7567 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7573 CallSeqStart, MemcpyFlags, DAG, dl);
7582 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7583 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7584 "Unexpected register residue for by-value argument.");
7586 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7590 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7600 "Unexpected load emitted during handling of pass-by-value "
7608 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7613 const CCValAssign &ByValVA = ArgLocs[
I++];
7618 CCValAssign &VA = ArgLocs[
I++];
7643 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7649 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7651 const unsigned OriginalValNo = VA.
getValNo();
7653 unsigned LoadOffset = 0;
7654 auto HandleCustomVecRegLoc = [&]() {
7655 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7656 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7657 "Expected custom RegLoc.");
7658 CCValAssign RegVA = ArgLocs[
I++];
7660 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7666 LoadOffset += PtrByteSize;
7672 HandleCustomVecRegLoc();
7673 HandleCustomVecRegLoc();
7675 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7676 ArgLocs[
I].getValNo() == OriginalValNo) {
7678 "Only 2 custom RegLocs expected for 64-bit codegen.");
7679 HandleCustomVecRegLoc();
7680 HandleCustomVecRegLoc();
7691 DAG.
getStore(Chain, dl, Arg, PtrOff,
7693 Subtarget.getFrameLowering()->getStackAlign()));
7700 "Unexpected register handling for calling convention.");
7706 "Custom register handling only expected for VarArg.");
7711 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7715 else if (Arg.getValueType().getFixedSizeInBits() <
7723 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7724 "Unexpected custom register for argument!");
7725 CCValAssign &GPR1 = VA;
7734 CCValAssign &PeekArg = ArgLocs[
I];
7737 CCValAssign &GPR2 = ArgLocs[
I++];
7745 if (!MemOpChains.
empty())
7750 if (CFlags.IsIndirect) {
7751 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7752 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7753 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7754 const MVT PtrVT = Subtarget.getScalarIntVT();
7755 const unsigned TOCSaveOffset =
7756 Subtarget.getFrameLowering()->getTOCSaveOffset();
7771 for (
auto Reg : RegsToPass) {
7776 const int SPDiff = 0;
7777 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7778 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7786 const Type *RetTy)
const {
7788 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7789 return CCInfo.CheckReturn(
7804 CCInfo.AnalyzeReturn(Outs,
7813 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7814 CCValAssign &VA = RVLocs[i];
7817 SDValue Arg = OutVals[RealResIdx];
7832 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7833 bool isLittleEndian = Subtarget.isLittleEndian();
7836 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7840 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7855 RetOps.push_back(Glue);
7857 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7861PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7866 EVT IntVT =
Op.getValueType();
7870 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7874 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7886 bool isPPC64 = Subtarget.isPPC64();
7887 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7896 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7902 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7907 bool isPPC64 = Subtarget.isPPC64();
7912 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7918 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7928PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7930 bool isPPC64 = Subtarget.isPPC64();
7935 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7941 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
7964 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7966 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
7968 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
7969 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
7976 bool isPPC64 = Subtarget.isPPC64();
7986 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
7988 Op.getOperand(0),
Op.getOperand(1));
7994 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
7995 Op.getOperand(0),
Op.getOperand(1));
7999 if (
Op.getValueType().isVector())
8000 return LowerVectorLoad(
Op, DAG);
8002 assert(
Op.getValueType() == MVT::i1 &&
8003 "Custom lowering only for i1 loads");
8012 MachineMemOperand *MMO =
LD->getMemOperand();
8016 BasePtr, MVT::i8, MMO);
8024 if (
Op.getOperand(1).getValueType().isVector())
8025 return LowerVectorStore(
Op, DAG);
8027 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8028 "Custom lowering only for i1 stores");
8038 MachineMemOperand *MMO =
ST->getMemOperand();
8047 assert(
Op.getValueType() == MVT::i1 &&
8048 "Custom lowering only for i1 results");
8076 EVT TrgVT =
Op.getValueType();
8100 if (SrcSize == 256) {
8111 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8117 SmallVector<int, 16> ShuffV;
8118 if (Subtarget.isLittleEndian())
8119 for (
unsigned i = 0; i < TrgNumElts; ++i)
8122 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8126 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8139 EVT ResVT =
Op.getValueType();
8140 EVT CmpVT =
Op.getOperand(0).getValueType();
8142 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8148 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8161 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8165 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8182 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8195 if (
LHS.getValueType() == MVT::f32)
8197 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8200 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8208 if (
LHS.getValueType() == MVT::f32)
8210 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8217 if (
LHS.getValueType() == MVT::f32)
8219 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8231 if (
Cmp.getValueType() == MVT::f32)
8233 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8236 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8241 if (
Cmp.getValueType() == MVT::f32)
8243 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8247 if (
Cmp.getValueType() == MVT::f32)
8249 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8253 if (
Cmp.getValueType() == MVT::f32)
8255 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8259 if (
Cmp.getValueType() == MVT::f32)
8261 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8270 case PPCISD::FCTIDZ:
8271 return PPCISD::STRICT_FCTIDZ;
8272 case PPCISD::FCTIWZ:
8273 return PPCISD::STRICT_FCTIWZ;
8274 case PPCISD::FCTIDUZ:
8275 return PPCISD::STRICT_FCTIDUZ;
8276 case PPCISD::FCTIWUZ:
8277 return PPCISD::STRICT_FCTIWUZ;
8279 return PPCISD::STRICT_FCFID;
8280 case PPCISD::FCFIDU:
8281 return PPCISD::STRICT_FCFIDU;
8282 case PPCISD::FCFIDS:
8283 return PPCISD::STRICT_FCFIDS;
8284 case PPCISD::FCFIDUS:
8285 return PPCISD::STRICT_FCFIDUS;
8292 bool IsStrict =
Op->isStrictFPOpcode();
8301 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8303 MVT DestTy =
Op.getSimpleValueType();
8304 assert(Src.getValueType().isFloatingPoint() &&
8305 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8306 DestTy == MVT::i64) &&
8307 "Invalid FP_TO_INT types");
8308 if (Src.getValueType() == MVT::f32) {
8312 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8317 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8323 Opc = IsSigned ? PPCISD::FCTIWZ
8324 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8327 assert((IsSigned || Subtarget.hasFPCVT()) &&
8328 "i64 FP_TO_UINT is supported only with FPCVT");
8329 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8331 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8343void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8345 const SDLoc &dl)
const {
8349 bool IsStrict =
Op->isStrictFPOpcode();
8352 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8353 (IsSigned || Subtarget.hasFPCVT());
8356 MachinePointerInfo MPI =
8364 Alignment =
Align(4);
8365 MachineMemOperand *MMO =
8371 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8375 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8376 !Subtarget.isLittleEndian()) {
8385 RLI.Alignment = Alignment;
8393 const SDLoc &dl)
const {
8396 if (
Op->isStrictFPOpcode())
8403 const SDLoc &dl)
const {
8404 bool IsStrict =
Op->isStrictFPOpcode();
8407 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8408 EVT SrcVT = Src.getValueType();
8409 EVT DstVT =
Op.getValueType();
8412 if (SrcVT == MVT::f128)
8413 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8417 if (SrcVT == MVT::ppcf128) {
8418 if (DstVT == MVT::i32) {
8423 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8434 {Op.getOperand(0), Lo, Hi}, Flags);
8437 {Res.getValue(1), Res}, Flags);
8443 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8467 {Chain, Src, FltOfs}, Flags);
8471 {Chain, Val}, Flags);
8474 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8492 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8493 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8496 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8498 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8499 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8510bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8515 if (
Op->isStrictFPOpcode())
8520 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8524 Op.getOperand(0).getValueType())) {
8526 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8531 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8532 LD->isNonTemporal())
8534 if (
LD->getMemoryVT() != MemVT)
8544 RLI.Ptr =
LD->getBasePtr();
8545 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8547 "Non-pre-inc AM on PPC?");
8552 RLI.Chain =
LD->getChain();
8553 RLI.MPI =
LD->getPointerInfo();
8554 RLI.IsDereferenceable =
LD->isDereferenceable();
8555 RLI.IsInvariant =
LD->isInvariant();
8556 RLI.Alignment =
LD->getAlign();
8557 RLI.AAInfo =
LD->getAAInfo();
8558 RLI.Ranges =
LD->getRanges();
8560 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8567bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8568 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8575 if (!Subtarget.hasP9Vector() &&
8579 for (SDUse &Use : Origin->
uses()) {
8582 if (
Use.getResNo() != 0)
8609 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8610 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8611 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8612 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8613 if (
Op->isStrictFPOpcode()) {
8615 Chain =
Op.getOperand(0);
8617 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8619 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8627 const SDLoc &dl)
const {
8628 assert((
Op.getValueType() == MVT::f32 ||
8629 Op.getValueType() == MVT::f64) &&
8630 "Invalid floating point type as target of conversion");
8631 assert(Subtarget.hasFPCVT() &&
8632 "Int to FP conversions with direct moves require FPCVT");
8633 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8634 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8637 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8656 for (
unsigned i = 1; i < NumConcat; ++i)
8663 const SDLoc &dl)
const {
8664 bool IsStrict =
Op->isStrictFPOpcode();
8665 unsigned Opc =
Op.getOpcode();
8666 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8669 "Unexpected conversion type");
8670 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8671 "Supports conversions to v2f64/v4f32 only.");
8675 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8678 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8683 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8685 SmallVector<int, 16> ShuffV;
8686 for (
unsigned i = 0; i < WideNumElts; ++i)
8689 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8690 int SaveElts = FourEltRes ? 4 : 2;
8691 if (Subtarget.isLittleEndian())
8692 for (
int i = 0; i < SaveElts; i++)
8693 ShuffV[i * Stride] = i;
8695 for (
int i = 1; i <= SaveElts; i++)
8696 ShuffV[i * Stride - 1] = i - 1;
8704 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8705 EVT ExtVT = Src.getValueType();
8706 if (Subtarget.hasP9Altivec())
8717 {Op.getOperand(0), Extend}, Flags);
8719 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8727 bool IsStrict =
Op->isStrictFPOpcode();
8728 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8733 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8735 EVT InVT = Src.getValueType();
8736 EVT OutVT =
Op.getValueType();
8739 return LowerINT_TO_FPVector(
Op, DAG, dl);
8742 if (
Op.getValueType() == MVT::f128)
8743 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8746 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8749 if (Src.getValueType() == MVT::i1) {
8761 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8762 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8763 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8765 assert((IsSigned || Subtarget.hasFPCVT()) &&
8766 "UINT_TO_FP is supported only with FPCVT");
8768 if (Src.getValueType() == MVT::i64) {
8783 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8784 !
Op->getFlags().hasApproximateFuncs()) {
8824 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8825 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8826 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8829 }
else if (Subtarget.hasLFIWAX() &&
8830 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8831 MachineMemOperand *MMO =
8833 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8837 Ops, MVT::i32, MMO);
8840 }
else if (Subtarget.hasFPCVT() &&
8841 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8842 MachineMemOperand *MMO =
8844 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8848 Ops, MVT::i32, MMO);
8851 }
else if (((Subtarget.hasLFIWAX() &&
8853 (Subtarget.hasFPCVT() &&
8868 "Expected an i32 store");
8874 RLI.Alignment =
Align(4);
8876 MachineMemOperand *MMO =
8878 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8881 PPCISD::LFIWZX : PPCISD::LFIWAX,
8882 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8883 Ops, MVT::i32, MMO);
8884 Chain =
Bits.getValue(1);
8892 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8896 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8905 assert(Src.getValueType() == MVT::i32 &&
8906 "Unhandled INT_TO_FP type in custom expander!");
8916 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8919 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8929 "Expected an i32 store");
8935 RLI.Alignment =
Align(4);
8938 MachineMemOperand *MMO =
8940 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8946 if (ReusingLoad && RLI.ResChain) {
8950 assert(Subtarget.isPPC64() &&
8951 "i32->FP without LFIWAX supported only on PPC64");
8960 Chain, dl, Ext64, FIdx,
8966 MVT::f64, dl, Chain, FIdx,
8975 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8979 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
8996 uint64_t
Mode = CVal->getZExtValue();
8997 assert(
Mode < 4 &&
"Unsupported rounding mode!");
8998 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
8999 if (Subtarget.isISA3_0())
9002 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9003 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9006 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9007 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9009 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9027 if (!Subtarget.isISA3_0()) {
9028 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9032 if (Subtarget.isPPC64()) {
9033 if (Subtarget.isISA3_0()) {
9038 PPC::RLDIMI, Dl, MVT::i64,
9043 NewFPSCR =
SDValue(InsertRN, 0);
9050 SDValue Addr = Subtarget.isLittleEndian()
9054 if (Subtarget.isISA3_0()) {
9055 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9057 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9059 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9062 PPC::RLWIMI, Dl, MVT::i32,
9063 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9064 DAG.getTargetConstant(30, Dl, MVT::i32),
9065 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9067 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9070 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9073 if (Subtarget.isISA3_0())
9079 PPC::MTFSF, Dl, MVT::Other,
9107 EVT VT =
Op.getValueType();
9112 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9123 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9127 "Stack slot adjustment is valid only on big endian subtargets!");
9130 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9157 EVT VT =
Op.getValueType();
9161 VT ==
Op.getOperand(1).getValueType() &&
9181 SDValue OutOps[] = { OutLo, OutHi };
9186 EVT VT =
Op.getValueType();
9190 VT ==
Op.getOperand(1).getValueType() &&
9210 SDValue OutOps[] = { OutLo, OutHi };
9216 EVT VT =
Op.getValueType();
9219 VT ==
Op.getOperand(1).getValueType() &&
9239 SDValue OutOps[] = { OutLo, OutHi };
9246 EVT VT =
Op.getValueType();
9253 EVT AmtVT =
Z.getValueType();
9263 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9264 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9276 static const MVT VTys[] = {
9277 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9280 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9283 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9288 EVT CanonicalVT = VTys[SplatSize-1];
9301 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9302 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9311 EVT DestVT = MVT::Other) {
9312 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9321 EVT DestVT = MVT::Other) {
9324 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9336 for (
unsigned i = 0; i != 16; ++i)
9357 EVT VecVT = V->getValueType(0);
9358 bool RightType = VecVT == MVT::v2f64 ||
9359 (HasP8Vector && VecVT == MVT::v4f32) ||
9360 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9364 bool IsSplat =
true;
9365 bool IsLoad =
false;
9371 if (V->isConstant())
9373 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9374 if (V->getOperand(i).isUndef())
9378 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9380 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9382 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9384 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9388 if (V->getOperand(i) != Op0 ||
9389 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9392 return !(IsSplat && IsLoad);
9402 (
Op.getValueType() != MVT::f128))
9407 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9410 if (!Subtarget.isLittleEndian())
9413 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9421 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9422 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9435 APFloat APFloatToConvert = ArgAPFloat;
9436 bool LosesInfo =
true;
9441 ArgAPFloat = APFloatToConvert;
9463 APFloat APFloatToConvert = ArgAPFloat;
9464 bool LosesInfo =
true;
9468 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9477 EVT Ty =
Op->getValueType(0);
9480 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9489 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9493 if (Ty == MVT::v2i64) {
9496 if (MemVT == MVT::i32) {
9498 Opcode = PPCISD::ZEXT_LD_SPLAT;
9500 Opcode = PPCISD::SEXT_LD_SPLAT;
9508 bool IsLittleEndian) {
9514 APInt ConstValue(VTSize, 0);
9518 unsigned BitPos = 0;
9526 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9527 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9531 for (
unsigned J = 0; J < 16; ++J) {
9533 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9535 if (ExtractValue == 0xFF)
9550 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9552 if (Subtarget.hasP10Vector()) {
9553 APInt BitMask(32, 0);
9559 BitMask != 0 && BitMask != 0xffff) {
9561 MachineSDNode *MSDNode =
9573 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9577 APInt APSplatBits, APSplatUndef;
9578 unsigned SplatBitSize;
9580 bool BVNIsConstantSplat =
9582 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9588 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9589 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9592 if ((
Op->getValueType(0) == MVT::v2f64) &&
9595 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9611 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9617 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9625 bool IsSplat64 =
false;
9626 uint64_t SplatBits = 0;
9627 int32_t SextVal = 0;
9628 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9630 if (SplatBitSize <= 32) {
9632 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9633 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9634 bool P9Vector = Subtarget.hasP9Vector();
9635 int32_t
Hi = P9Vector ? 127 : 15;
9636 int32_t
Lo = P9Vector ? -128 : -16;
9637 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9638 SextVal =
static_cast<int32_t
>(SplatBits);
9642 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9643 unsigned NewOpcode = PPCISD::LD_SPLAT;
9649 const SDValue *InputLoad = &
Op.getOperand(0);
9654 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9655 unsigned ElementSize =
9656 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9658 assert(((ElementSize == 2 * MemorySize)
9659 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9660 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9661 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9662 "Unmatched element size and opcode!\n");
9667 unsigned NumUsesOfInputLD = 128 / ElementSize;
9669 if (BVInOp.isUndef())
9684 if (NumUsesOfInputLD == 1 &&
9685 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9686 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9687 Subtarget.hasLFIWAX()))
9695 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9696 Subtarget.isISA3_1() && ElementSize <= 16)
9699 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9701 Subtarget.hasVSX()) {
9708 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9709 LD->getMemoryVT(),
LD->getMemOperand());
9721 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9723 Subtarget.hasP8Vector()))
9729 unsigned SplatSize = SplatBitSize / 8;
9734 if (SplatBits == 0) {
9736 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9748 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9750 Op.getValueType(), DAG, dl);
9752 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9757 if (Subtarget.hasP9Vector() && SplatSize == 1)
9763 if (SextVal >= -16 && SextVal <= 15) {
9766 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9776 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9782 switch (SplatSize) {
9786 IID = Intrinsic::ppc_altivec_vupklsb;
9790 IID = Intrinsic::ppc_altivec_vextsb2w;
9794 IID = Intrinsic::ppc_altivec_vextsb2d;
9801 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9810 if (SextVal >= -32 && SextVal <= 31) {
9815 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9816 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9819 if (VT ==
Op.getValueType())
9828 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9842 static const signed char SplatCsts[] = {
9843 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9844 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9847 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9850 int i = SplatCsts[idx];
9854 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9857 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9859 static const unsigned IIDs[] = {
9860 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9861 Intrinsic::ppc_altivec_vslw
9868 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9870 static const unsigned IIDs[] = {
9871 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9872 Intrinsic::ppc_altivec_vsrw
9879 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9880 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9882 static const unsigned IIDs[] = {
9883 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9884 Intrinsic::ppc_altivec_vrlw
9891 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9893 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9897 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9899 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9903 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9905 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9918 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9919 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9920 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9936 if (LHSID == (1*9+2)*9+3)
return LHS;
9937 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9949 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9950 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9951 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9952 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9955 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9956 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9957 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9958 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9961 for (
unsigned i = 0; i != 16; ++i)
9962 ShufIdxs[i] = (i&3)+0;
9965 for (
unsigned i = 0; i != 16; ++i)
9966 ShufIdxs[i] = (i&3)+4;
9969 for (
unsigned i = 0; i != 16; ++i)
9970 ShufIdxs[i] = (i&3)+8;
9973 for (
unsigned i = 0; i != 16; ++i)
9974 ShufIdxs[i] = (i&3)+12;
9995 const unsigned BytesInVector = 16;
9996 bool IsLE = Subtarget.isLittleEndian();
10000 unsigned ShiftElts = 0, InsertAtByte = 0;
10004 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10005 0, 15, 14, 13, 12, 11, 10, 9};
10006 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10007 1, 2, 3, 4, 5, 6, 7, 8};
10009 ArrayRef<int>
Mask =
N->getMask();
10010 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10022 bool FoundCandidate =
false;
10026 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10029 for (
unsigned i = 0; i < BytesInVector; ++i) {
10030 unsigned CurrentElement =
Mask[i];
10033 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10036 bool OtherElementsInOrder =
true;
10039 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10046 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10047 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10048 OtherElementsInOrder =
false;
10055 if (OtherElementsInOrder) {
10062 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10063 : BigEndianShifts[CurrentElement & 0xF];
10064 Swap = CurrentElement < BytesInVector;
10066 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10067 FoundCandidate =
true;
10072 if (!FoundCandidate)
10082 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10084 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10087 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10096 const unsigned NumHalfWords = 8;
10097 const unsigned BytesInVector = NumHalfWords * 2;
10102 bool IsLE = Subtarget.isLittleEndian();
10106 unsigned ShiftElts = 0, InsertAtByte = 0;
10110 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10111 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10114 uint32_t OriginalOrderLow = 0x1234567;
10115 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10118 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10119 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10136 bool FoundCandidate =
false;
10139 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10140 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10142 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10143 uint32_t TargetOrder = 0x0;
10150 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10151 TargetOrder = OriginalOrderLow;
10155 if (MaskOneElt == VINSERTHSrcElem &&
10156 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10157 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10158 FoundCandidate =
true;
10164 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10166 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10168 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10169 : BigEndianShifts[MaskOneElt & 0x7];
10170 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10171 Swap = MaskOneElt < NumHalfWords;
10172 FoundCandidate =
true;
10178 if (!FoundCandidate)
10190 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10193 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10198 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10213 auto ShuffleMask = SVN->
getMask();
10228 ShuffleMask = CommutedSV->
getMask();
10237 APInt APSplatValue, APSplatUndef;
10238 unsigned SplatBitSize;
10241 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10253 bool IsLE = Subtarget.isLittleEndian();
10254 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10255 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10256 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10258 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10259 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10260 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10268 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10269 SplatVal |= (SplatVal << SplatBitSize);
10272 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10283 assert(
Op.getValueType() == MVT::v1i128 &&
10284 "Only set v1i128 as custom, other type shouldn't reach here!");
10289 if (SHLAmt % 8 == 0) {
10290 std::array<int, 16>
Mask;
10291 std::iota(
Mask.begin(),
Mask.end(), 0);
10292 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10321 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10326 V1 =
Op.getOperand(0);
10327 V2 =
Op.getOperand(1);
10329 EVT VT =
Op.getValueType();
10330 bool isLittleEndian = Subtarget.isLittleEndian();
10332 unsigned ShiftElts, InsertAtByte;
10338 bool IsPermutedLoad =
false;
10340 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10350 if (IsPermutedLoad) {
10351 assert((isLittleEndian || IsFourByte) &&
10352 "Unexpected size for permuted load on big endian target");
10353 SplatIdx += IsFourByte ? 2 : 1;
10354 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10355 "Splat of a value outside of the loaded memory");
10360 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10363 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10365 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10369 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10382 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10385 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10394 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10397 if (Subtarget.hasP9Vector() &&
10407 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10409 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10413 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10418 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10420 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10421 return SplatInsertNode;
10424 if (Subtarget.hasP9Altivec()) {
10426 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10429 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10433 if (Subtarget.hasVSX() &&
10441 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10446 if (Subtarget.hasVSX() &&
10454 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10459 if (Subtarget.hasP9Vector()) {
10479 if (Subtarget.hasVSX()) {
10492 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10500 if (V2.isUndef()) {
10513 (Subtarget.hasP8Altivec() && (
10524 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10534 (Subtarget.hasP8Altivec() && (
10542 ArrayRef<int> PermMask = SVOp->
getMask();
10545 unsigned PFIndexes[4];
10546 bool isFourElementShuffle =
true;
10547 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10549 unsigned EltNo = 8;
10550 for (
unsigned j = 0;
j != 4; ++
j) {
10551 if (PermMask[i * 4 + j] < 0)
10554 unsigned ByteSource = PermMask[i * 4 +
j];
10555 if ((ByteSource & 3) != j) {
10556 isFourElementShuffle =
false;
10561 EltNo = ByteSource / 4;
10562 }
else if (EltNo != ByteSource / 4) {
10563 isFourElementShuffle =
false;
10567 PFIndexes[i] = EltNo;
10575 if (isFourElementShuffle) {
10577 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10578 PFIndexes[2] * 9 + PFIndexes[3];
10581 unsigned Cost = (PFEntry >> 30);
10601 if (V2.isUndef()) V2 = V1;
10603 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10609 unsigned Opcode = PPCISD::VPERM;
10612 bool NeedSwap =
false;
10613 bool isLittleEndian = Subtarget.isLittleEndian();
10614 bool isPPC64 = Subtarget.isPPC64();
10616 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10618 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10619 "XXPERM instead\n");
10620 Opcode = PPCISD::XXPERM;
10628 NeedSwap = !NeedSwap;
10663 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10665 if (V1HasXXSWAPD) {
10668 else if (SrcElt < 16)
10671 if (V2HasXXSWAPD) {
10674 else if (SrcElt > 15)
10683 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10684 if (isLittleEndian)
10686 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10689 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10692 if (V1HasXXSWAPD) {
10696 if (V2HasXXSWAPD) {
10701 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10702 if (ValType != MVT::v2f64)
10708 ShufflesHandledWithVPERM++;
10712 if (Opcode == PPCISD::XXPERM) {
10713 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10715 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10718 dbgs() <<
"With the following permute control vector:\n";
10722 if (Opcode == PPCISD::XXPERM)
10723 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10727 if (isLittleEndian)
10733 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10745 switch (IntrinsicID) {
10749 case Intrinsic::ppc_altivec_vcmpbfp_p:
10753 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10757 case Intrinsic::ppc_altivec_vcmpequb_p:
10761 case Intrinsic::ppc_altivec_vcmpequh_p:
10765 case Intrinsic::ppc_altivec_vcmpequw_p:
10769 case Intrinsic::ppc_altivec_vcmpequd_p:
10770 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10776 case Intrinsic::ppc_altivec_vcmpneb_p:
10777 case Intrinsic::ppc_altivec_vcmpneh_p:
10778 case Intrinsic::ppc_altivec_vcmpnew_p:
10779 case Intrinsic::ppc_altivec_vcmpnezb_p:
10780 case Intrinsic::ppc_altivec_vcmpnezh_p:
10781 case Intrinsic::ppc_altivec_vcmpnezw_p:
10782 if (Subtarget.hasP9Altivec()) {
10783 switch (IntrinsicID) {
10786 case Intrinsic::ppc_altivec_vcmpneb_p:
10789 case Intrinsic::ppc_altivec_vcmpneh_p:
10792 case Intrinsic::ppc_altivec_vcmpnew_p:
10795 case Intrinsic::ppc_altivec_vcmpnezb_p:
10798 case Intrinsic::ppc_altivec_vcmpnezh_p:
10801 case Intrinsic::ppc_altivec_vcmpnezw_p:
10809 case Intrinsic::ppc_altivec_vcmpgefp_p:
10813 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10817 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10821 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10825 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10829 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10830 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10836 case Intrinsic::ppc_altivec_vcmpgtub_p:
10840 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10844 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10848 case Intrinsic::ppc_altivec_vcmpgtud_p:
10849 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10856 case Intrinsic::ppc_altivec_vcmpequq:
10857 case Intrinsic::ppc_altivec_vcmpgtsq:
10858 case Intrinsic::ppc_altivec_vcmpgtuq:
10859 if (!Subtarget.isISA3_1())
10861 switch (IntrinsicID) {
10864 case Intrinsic::ppc_altivec_vcmpequq:
10867 case Intrinsic::ppc_altivec_vcmpgtsq:
10870 case Intrinsic::ppc_altivec_vcmpgtuq:
10877 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10878 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10879 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10880 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10881 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10882 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10883 if (Subtarget.hasVSX()) {
10884 switch (IntrinsicID) {
10885 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10888 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10891 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10894 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10897 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10900 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10910 case Intrinsic::ppc_altivec_vcmpbfp:
10913 case Intrinsic::ppc_altivec_vcmpeqfp:
10916 case Intrinsic::ppc_altivec_vcmpequb:
10919 case Intrinsic::ppc_altivec_vcmpequh:
10922 case Intrinsic::ppc_altivec_vcmpequw:
10925 case Intrinsic::ppc_altivec_vcmpequd:
10926 if (Subtarget.hasP8Altivec())
10931 case Intrinsic::ppc_altivec_vcmpneb:
10932 case Intrinsic::ppc_altivec_vcmpneh:
10933 case Intrinsic::ppc_altivec_vcmpnew:
10934 case Intrinsic::ppc_altivec_vcmpnezb:
10935 case Intrinsic::ppc_altivec_vcmpnezh:
10936 case Intrinsic::ppc_altivec_vcmpnezw:
10937 if (Subtarget.hasP9Altivec())
10938 switch (IntrinsicID) {
10941 case Intrinsic::ppc_altivec_vcmpneb:
10944 case Intrinsic::ppc_altivec_vcmpneh:
10947 case Intrinsic::ppc_altivec_vcmpnew:
10950 case Intrinsic::ppc_altivec_vcmpnezb:
10953 case Intrinsic::ppc_altivec_vcmpnezh:
10956 case Intrinsic::ppc_altivec_vcmpnezw:
10963 case Intrinsic::ppc_altivec_vcmpgefp:
10966 case Intrinsic::ppc_altivec_vcmpgtfp:
10969 case Intrinsic::ppc_altivec_vcmpgtsb:
10972 case Intrinsic::ppc_altivec_vcmpgtsh:
10975 case Intrinsic::ppc_altivec_vcmpgtsw:
10978 case Intrinsic::ppc_altivec_vcmpgtsd:
10979 if (Subtarget.hasP8Altivec())
10984 case Intrinsic::ppc_altivec_vcmpgtub:
10987 case Intrinsic::ppc_altivec_vcmpgtuh:
10990 case Intrinsic::ppc_altivec_vcmpgtuw:
10993 case Intrinsic::ppc_altivec_vcmpgtud:
10994 if (Subtarget.hasP8Altivec())
10999 case Intrinsic::ppc_altivec_vcmpequq_p:
11000 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11001 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11002 if (!Subtarget.isISA3_1())
11004 switch (IntrinsicID) {
11007 case Intrinsic::ppc_altivec_vcmpequq_p:
11010 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11013 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11027 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11033 auto MapNodeWithSplatVector =
11034 [&](
unsigned Opcode,
11035 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11040 Ops.append(ExtraOps.begin(), ExtraOps.end());
11041 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11044 switch (IntrinsicID) {
11045 case Intrinsic::thread_pointer:
11047 if (Subtarget.isPPC64())
11051 case Intrinsic::ppc_rldimi: {
11052 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11054 APInt
Mask =
Op.getConstantOperandAPInt(4);
11056 return Op.getOperand(2);
11057 if (
Mask.isAllOnes())
11059 uint64_t SH =
Op.getConstantOperandVal(3);
11060 unsigned MB = 0, ME = 0;
11064 if (ME < 63 - SH) {
11067 }
else if (ME > 63 - SH) {
11073 {Op.getOperand(2), Src,
11074 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11075 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11079 case Intrinsic::ppc_rlwimi: {
11080 APInt
Mask =
Op.getConstantOperandAPInt(4);
11082 return Op.getOperand(2);
11083 if (
Mask.isAllOnes())
11086 unsigned MB = 0, ME = 0;
11090 PPC::RLWIMI, dl, MVT::i32,
11091 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11092 DAG.getTargetConstant(MB, dl, MVT::i32),
11093 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11097 case Intrinsic::ppc_bcdshift:
11098 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11099 case Intrinsic::ppc_bcdshiftround:
11100 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11101 case Intrinsic::ppc_bcdtruncate:
11102 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11103 case Intrinsic::ppc_bcdunsignedtruncate:
11104 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11105 case Intrinsic::ppc_bcdunsignedshift:
11106 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11108 case Intrinsic::ppc_rlwnm: {
11109 if (
Op.getConstantOperandVal(3) == 0)
11111 unsigned MB = 0, ME = 0;
11116 {Op.getOperand(1), Op.getOperand(2),
11117 DAG.getTargetConstant(MB, dl, MVT::i32),
11118 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11122 case Intrinsic::ppc_mma_disassemble_acc: {
11123 if (Subtarget.isISAFuture()) {
11124 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11135 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11136 Subtarget.isLittleEndian() ? Value2 :
Value,
11137 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11141 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11142 Subtarget.isLittleEndian() ? Value2 :
Value,
11143 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11147 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11148 Subtarget.isLittleEndian() ?
Value : Value2,
11149 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11153 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11154 Subtarget.isLittleEndian() ?
Value : Value2,
11155 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11162 case Intrinsic::ppc_vsx_disassemble_pair: {
11165 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11167 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11170 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11172 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11173 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11181 case Intrinsic::ppc_build_dmr: {
11184 for (
int i = 1; i < 9; i += 2) {
11192 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11199 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11200 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11202 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11203 "Specify P of 0 or 1 for lower or upper 512 bytes");
11204 unsigned HiLo = Idx->getSExtValue();
11208 Opcode = PPC::DMXXEXTFDMR512;
11209 Subx = PPC::sub_wacc_lo;
11211 Opcode = PPC::DMXXEXTFDMR512_HI;
11212 Subx = PPC::sub_wacc_hi;
11215 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11219 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11223 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11224 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11226 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11227 "Specify a dmr row pair 0-3");
11228 unsigned IdxVal = Idx->getSExtValue();
11232 Subx = PPC::sub_dmrrowp0;
11235 Subx = PPC::sub_dmrrowp1;
11238 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11241 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11245 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11251 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11255 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11256 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11258 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11259 "Specify P of 0 or 1 for lower or upper 512 bytes");
11260 unsigned HiLo = Idx->getSExtValue();
11264 Opcode = PPCISD::INST512;
11265 Subx = PPC::sub_wacc_lo;
11267 Opcode = PPCISD::INST512HI;
11268 Subx = PPC::sub_wacc_hi;
11274 Op.getOperand(1), Wacc, SubReg),
11278 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11279 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11281 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11282 "Specify a dmr row pair 0-3");
11283 unsigned IdxVal = Idx->getSExtValue();
11287 Subx = PPC::sub_dmrrowp0;
11290 Subx = PPC::sub_dmrrowp1;
11293 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11296 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11302 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11304 Op.getOperand(1), DMRRowp, SubReg),
11308 case Intrinsic::ppc_mma_xxmfacc:
11309 case Intrinsic::ppc_mma_xxmtacc: {
11311 if (!Subtarget.isISAFuture())
11322 case Intrinsic::ppc_unpack_longdouble: {
11324 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11325 "Argument of long double unpack must be 0 or 1!");
11328 Idx->getValueType(0)));
11331 case Intrinsic::ppc_compare_exp_lt:
11332 case Intrinsic::ppc_compare_exp_gt:
11333 case Intrinsic::ppc_compare_exp_eq:
11334 case Intrinsic::ppc_compare_exp_uo: {
11336 switch (IntrinsicID) {
11337 case Intrinsic::ppc_compare_exp_lt:
11340 case Intrinsic::ppc_compare_exp_gt:
11343 case Intrinsic::ppc_compare_exp_eq:
11346 case Intrinsic::ppc_compare_exp_uo:
11352 PPC::SELECT_CC_I4, dl, MVT::i32,
11353 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11354 Op.getOperand(1), Op.getOperand(2)),
11356 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11357 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11360 case Intrinsic::ppc_test_data_class: {
11361 EVT OpVT =
Op.getOperand(1).getValueType();
11362 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11363 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11376 {Op.getOperand(2), Op.getOperand(1)}),
11378 if (Subtarget.isISA3_1()) {
11385 TestDataClass, SubRegIdx),
11388 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11394 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11395 DAG.getConstant(0, dl, MVT::i32),
11396 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11399 case Intrinsic::ppc_fnmsub: {
11400 EVT VT =
Op.getOperand(1).getValueType();
11401 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11406 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11407 Op.getOperand(2),
Op.getOperand(3));
11409 case Intrinsic::ppc_convert_f128_to_ppcf128:
11410 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11411 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11412 ? RTLIB::CONVERT_PPCF128_F128
11413 : RTLIB::CONVERT_F128_PPCF128;
11415 std::pair<SDValue, SDValue>
Result =
11416 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11420 case Intrinsic::ppc_maxfe:
11421 case Intrinsic::ppc_maxfl:
11422 case Intrinsic::ppc_maxfs:
11423 case Intrinsic::ppc_minfe:
11424 case Intrinsic::ppc_minfl:
11425 case Intrinsic::ppc_minfs: {
11426 EVT VT =
Op.getValueType();
11429 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11430 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11433 if (IntrinsicID == Intrinsic::ppc_minfe ||
11434 IntrinsicID == Intrinsic::ppc_minfl ||
11435 IntrinsicID == Intrinsic::ppc_minfs)
11456 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11457 Op.getOperand(1),
Op.getOperand(2),
11468 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11476 switch (
Op.getConstantOperandVal(1)) {
11481 Bitx = PPC::sub_eq;
11482 SetOp = PPCISD::SETBC;
11487 Bitx = PPC::sub_eq;
11488 SetOp = PPCISD::SETBCR;
11493 Bitx = PPC::sub_lt;
11494 SetOp = PPCISD::SETBC;
11499 Bitx = PPC::sub_lt;
11500 SetOp = PPCISD::SETBCR;
11505 if (Subtarget.isISA3_1()) {
11510 CR6Reg, SubRegIdx, GlueOp),
11512 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11536 unsigned IntrinsicID =
Op.getConstantOperandVal(1);
11538 switch (IntrinsicID) {
11539 case Intrinsic::ppc_amo_lwat_csne:
11540 case Intrinsic::ppc_amo_ldat_csne:
11546 EVT VT = IntrinsicID == Intrinsic::ppc_amo_ldat_csne ? MVT::i64 : MVT::i32;
11553 Args.emplace_back(CmpVal, Ty);
11554 Args.emplace_back(NewVal, Ty);
11555 Args.emplace_back(Ptr, IntPtrTy);
11561 const char *SymName = IntrinsicID == Intrinsic::ppc_amo_ldat_csne
11562 ?
"__ldat_csne_pseudo"
11563 :
"__lwat_csne_pseudo";
11567 TargetLowering::CallLoweringInfo CLI(DAG);
11583 switch (
Op.getConstantOperandVal(ArgStart)) {
11584 case Intrinsic::ppc_cfence: {
11585 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11586 SDValue Val =
Op.getOperand(ArgStart + 1);
11588 if (Ty == MVT::i128) {
11593 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11596 Opcode,
DL, MVT::Other,
11601 case Intrinsic::ppc_disassemble_dmr: {
11603 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11604 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11605 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11607 case Intrinsic::ppc_amo_stwat:
11608 case Intrinsic::ppc_amo_stdat: {
11611 SDValue Ptr =
Op.getOperand(ArgStart + 1);
11612 SDValue Val =
Op.getOperand(ArgStart + 2);
11615 return DAG.
getNode(PPCISD::STAT, dl, MVT::Other, Chain, Val, Ptr, FC);
11626 if (!Subtarget.isPPC64())
11634 int VectorIndex = 0;
11635 if (Subtarget.isLittleEndian())
11647 "Expecting an atomic compare-and-swap here.");
11650 EVT MemVT = AtomicNode->getMemoryVT();
11668 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11669 Ops.push_back(AtomicNode->getOperand(i));
11671 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11672 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11674 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11681 EVT MemVT =
N->getMemoryVT();
11683 "Expect quadword atomic operations");
11685 unsigned Opc =
N->getOpcode();
11690 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11693 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11694 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11695 Ops.push_back(
N->getOperand(
I));
11697 Ops, MemVT,
N->getMemOperand());
11704 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11711 SDVTList Tys = DAG.
getVTList(MVT::Other);
11714 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11720 Ops.push_back(ValLo);
11721 Ops.push_back(ValHi);
11722 Ops.push_back(
N->getOperand(2));
11724 N->getMemOperand());
11736 enum DataClassMask {
11738 DC_NEG_INF = 1 << 4,
11739 DC_POS_INF = 1 << 5,
11740 DC_NEG_ZERO = 1 << 2,
11741 DC_POS_ZERO = 1 << 3,
11742 DC_NEG_SUBNORM = 1,
11743 DC_POS_SUBNORM = 1 << 1,
11746 EVT VT =
Op.getValueType();
11748 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11749 : VT == MVT::f64 ? PPC::XSTSTDCDP
11760 return DAG.
getNOT(Dl, Rev, MVT::i1);
11767 TestOp, Dl, MVT::i32,
11769 DC_NEG_ZERO | DC_POS_ZERO |
11770 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11776 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11782 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11787 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11800 bool IsQuiet = Mask &
fcQNan;
11806 if (VT == MVT::f128) {
11810 QuietMask = 0x8000;
11811 }
else if (VT == MVT::f64) {
11812 if (Subtarget.isPPC64()) {
11823 QuietMask = 0x80000;
11824 }
else if (VT == MVT::f32) {
11826 QuietMask = 0x400000;
11842 unsigned NativeMask = 0;
11844 NativeMask |= DC_NAN;
11846 NativeMask |= DC_NEG_INF;
11848 NativeMask |= DC_POS_INF;
11850 NativeMask |= DC_NEG_ZERO;
11852 NativeMask |= DC_POS_ZERO;
11854 NativeMask |= DC_NEG_SUBNORM;
11856 NativeMask |= DC_POS_SUBNORM;
11859 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11861 TestOp, Dl, MVT::i32,
11870 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11872 uint64_t RHSC =
Op.getConstantOperandVal(1);
11875 if (
LHS.getValueType() == MVT::ppcf128) {
11899 bool Future = Subtarget.isISAFuture();
11902 "Mask predication not supported");
11905 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11906 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11910 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11913 VPLD->getMemoryVT(), VPLD->getMemOperand());
11920 "Mask predication not supported");
11925 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11926 bool Future = Subtarget.isISAFuture();
11927 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11930 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11933 SDVTList Tys = DAG.
getVTList(MVT::Other);
11936 VPST->getMemoryVT(), VPST->getMemOperand());
11947 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11949 int64_t
IntVal =
Op.getConstantOperandVal(0);
11950 if (IntVal >= -16 && IntVal <= 15)
11956 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11961 MachineMemOperand *MMO =
11963 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11966 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
11970 return Bits.getValue(0);
11986 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11991 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11998 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11999 MachinePointerInfo());
12006 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
12012 "Should only be called for ISD::INSERT_VECTOR_ELT");
12016 EVT VT =
Op.getValueType();
12021 if (VT == MVT::v2f64 &&
C)
12024 if (Subtarget.hasP9Vector()) {
12033 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12039 BitcastLoad,
Op.getOperand(2));
12040 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12044 if (Subtarget.isISA3_1()) {
12045 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12049 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12050 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12060 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12063 unsigned InsertAtElement =
C->getZExtValue();
12064 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12065 if (Subtarget.isLittleEndian()) {
12066 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12068 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
12080 EVT VT =
Op.getValueType();
12081 bool IsV1024i1 = VT == MVT::v1024i1;
12082 bool IsV2048i1 = VT == MVT::v2048i1;
12086 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12088 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12089 "Dense Math support required.");
12090 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12099 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12100 MachineMemOperand *NewMMO =
12108 DAG.
getVTList(MVT::v256i1, MVT::Other),
12109 LoadOps, MVT::v256i1, NewMMO);
12114 if (Subtarget.isLittleEndian()) {
12115 std::reverse(Loads.
begin(), Loads.
end());
12116 std::reverse(LoadChains.
begin(), LoadChains.
end());
12128 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12134 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12137 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12146 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12149 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12154 {RC, Lo, LoSub, Hi, HiSub}),
12164 EVT VT =
Op.getValueType();
12166 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12167 return LowerDMFVectorLoad(
Op, DAG);
12169 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12173 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12174 "Type unsupported without MMA");
12175 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12176 "Type unsupported without paired vector support");
12180 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12189 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12191 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12200 if (Subtarget.isLittleEndian()) {
12201 std::reverse(Loads.
begin(), Loads.
end());
12202 std::reverse(LoadChains.
begin(), LoadChains.
end());
12206 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12222 bool IsV1024i1 = VT == MVT::v1024i1;
12223 bool IsV2048i1 = VT == MVT::v2048i1;
12227 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12229 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12230 "Dense Math support required.");
12231 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12233 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12236 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12241 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12245 MachineSDNode *ExtNode =
12249 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12255 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12261 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12267 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12272 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12277 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12282 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12286 MachineSDNode *ExtNode =
12287 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12291 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12294 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12298 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12303 if (Subtarget.isLittleEndian())
12304 std::reverse(Values.
begin(), Values.
end());
12306 SDVTList Tys = DAG.
getVTList(MVT::Other);
12308 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12312 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12313 MachineMemOperand *NewMMO =
12320 Ops[2] = Values[Idx];
12322 MVT::v256i1, NewMMO);
12338 EVT StoreVT =
Value.getValueType();
12340 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12341 return LowerDMFVectorStore(
Op, DAG);
12343 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12347 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12348 "Type unsupported without MMA");
12349 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12350 "Type unsupported without paired vector support");
12354 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12362 unsigned NumVecs = 2;
12363 if (StoreVT == MVT::v512i1) {
12364 if (Subtarget.isISAFuture()) {
12365 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12367 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12370 Value2 =
SDValue(ExtNode, 1);
12375 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12376 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12378 if (Subtarget.isISAFuture()) {
12379 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12380 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12381 Idx > 1 ? Value2 :
Value,
12384 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12388 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12402 if (
Op.getValueType() == MVT::v4i32) {
12419 LHS,
RHS, DAG, dl, MVT::v4i32);
12422 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12427 }
else if (
Op.getValueType() == MVT::v16i8) {
12429 bool isLittleEndian = Subtarget.isLittleEndian();
12433 LHS,
RHS, DAG, dl, MVT::v8i16);
12438 LHS,
RHS, DAG, dl, MVT::v8i16);
12446 for (
unsigned i = 0; i != 8; ++i) {
12447 if (isLittleEndian) {
12449 Ops[i*2+1] = 2*i+16;
12452 Ops[i*2+1] = 2*i+1+16;
12455 if (isLittleEndian)
12465 bool IsStrict =
Op->isStrictFPOpcode();
12466 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12467 !Subtarget.hasP9Vector())
12477 "Should only be called for ISD::FP_EXTEND");
12481 if (
Op.getValueType() != MVT::v2f64 ||
12482 Op.getOperand(0).getValueType() != MVT::v2f32)
12494 "Node should have 2 operands with second one being a constant!");
12506 int DWord = Idx >> 1;
12509 if (Subtarget.isLittleEndian())
12512 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12526 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12528 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12529 LD->getMemoryVT(),
LD->getMemOperand());
12534 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12539 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12541 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12542 LD->getMemoryVT(),
LD->getMemOperand());
12543 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12554 if (STI.useCRBits())
12571 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12572 if (STI.useCRBits())
12580 SDNode *
N =
Op.getNode();
12581 EVT VT =
N->getValueType(0);
12582 EVT CarryType =
N->getValueType(1);
12583 unsigned Opc =
N->getOpcode();
12585 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12587 N->getOperand(0),
N->getOperand(1));
12599 SDNode *
N =
Op.getNode();
12600 unsigned Opc =
N->getOpcode();
12601 EVT VT =
N->getValueType(0);
12602 EVT CarryType =
N->getValueType(1);
12603 SDValue CarryOp =
N->getOperand(2);
12605 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12611 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12625 EVT VT =
Op.getNode()->getValueType(0);
12651 EVT VT =
Op.getNode()->getValueType(0);
12680 EVT OpVT =
A.getValueType();
12681 EVT ResVT =
Op.getValueType();
12686 if (Subtarget.isPPC64() && OpVT == MVT::i32) {
12696 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12714 switch (
Op.getOpcode()) {
12734 return LowerSSUBO(
Op, DAG);
12736 return LowerSADDO(
Op, DAG);
12748 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12769 return LowerSET_ROUNDING(
Op, DAG);
12776 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12777 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12789 return LowerFP_ROUND(
Op, DAG);
12794 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
12803 return LowerINTRINSIC_VOID(
Op, DAG);
12805 return LowerBSWAP(
Op, DAG);
12807 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12809 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12811 return LowerIS_FPCLASS(
Op, DAG);
12814 return LowerADDSUBO(
Op, DAG);
12817 return LowerADDSUBO_CARRY(
Op, DAG);
12819 return LowerUCMP(
Op, DAG);
12825 if (
Op->getFlags().hasNoFPExcept())
12829 return LowerVP_LOAD(
Op, DAG);
12830 case ISD::VP_STORE:
12831 return LowerVP_STORE(
Op, DAG);
12839 switch (
N->getOpcode()) {
12841 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12858 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12861 assert(
N->getValueType(0) == MVT::i1 &&
12862 "Unexpected result type for CTR decrement intrinsic");
12864 N->getValueType(0));
12874 switch (
N->getConstantOperandVal(0)) {
12875 case Intrinsic::ppc_pack_longdouble:
12877 N->getOperand(2),
N->getOperand(1)));
12879 case Intrinsic::ppc_maxfe:
12880 case Intrinsic::ppc_minfe:
12881 case Intrinsic::ppc_fnmsub:
12882 case Intrinsic::ppc_convert_f128_to_ppcf128:
12889 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12892 EVT VT =
N->getValueType(0);
12894 if (VT == MVT::i64) {
12907 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12911 Results.push_back(LoweredValue);
12912 if (
N->isStrictFPOpcode())
12917 if (!
N->getValueType(0).isVector())
12950 return Builder.CreateIntrinsic(Id, {});
12956 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12958 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12959 "Only 8/16/32/64-bit atomic loads supported");
12965 IntID = Intrinsic::ppc_lbarx;
12966 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12969 IntID = Intrinsic::ppc_lharx;
12970 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12973 IntID = Intrinsic::ppc_lwarx;
12976 IntID = Intrinsic::ppc_ldarx;
12980 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12982 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12993 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12994 "Only 8/16/32/64-bit atomic loads supported");
13000 IntID = Intrinsic::ppc_stbcx;
13001 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13004 IntID = Intrinsic::ppc_sthcx;
13005 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13008 IntID = Intrinsic::ppc_stwcx;
13011 IntID = Intrinsic::ppc_stdcx;
13015 if (SZ == 8 || SZ == 16)
13016 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13018 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13020 return Builder.CreateXor(
Call, Builder.getInt32(1));
13043 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
13053 unsigned AtomicSize,
13054 unsigned BinOpcode,
13055 unsigned CmpOpcode,
13056 unsigned CmpPred)
const {
13060 auto LoadMnemonic = PPC::LDARX;
13061 auto StoreMnemonic = PPC::STDCX;
13062 switch (AtomicSize) {
13066 LoadMnemonic = PPC::LBARX;
13067 StoreMnemonic = PPC::STBCX;
13068 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13071 LoadMnemonic = PPC::LHARX;
13072 StoreMnemonic = PPC::STHCX;
13073 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13076 LoadMnemonic = PPC::LWARX;
13077 StoreMnemonic = PPC::STWCX;
13080 LoadMnemonic = PPC::LDARX;
13081 StoreMnemonic = PPC::STDCX;
13097 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13099 F->insert(It, loopMBB);
13101 F->insert(It, loop2MBB);
13102 F->insert(It, exitMBB);
13108 Register TmpReg = (!BinOpcode) ? incr :
13109 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13110 : &PPC::GPRCRegClass);
13135 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13140 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13142 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13143 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13144 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13174 switch(
MI.getOpcode()) {
13178 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13179 &
MI.getMF()->getRegInfo());
13203 case PPC::EXTSB8_32_64:
13204 case PPC::EXTSB8_rec:
13205 case PPC::EXTSB_rec:
13208 case PPC::EXTSH8_32_64:
13209 case PPC::EXTSH8_rec:
13210 case PPC::EXTSH_rec:
13212 case PPC::EXTSWSLI:
13213 case PPC::EXTSWSLI_32_64:
13214 case PPC::EXTSWSLI_32_64_rec:
13215 case PPC::EXTSWSLI_rec:
13216 case PPC::EXTSW_32:
13217 case PPC::EXTSW_32_64:
13218 case PPC::EXTSW_32_64_rec:
13219 case PPC::EXTSW_rec:
13222 case PPC::SRAWI_rec:
13223 case PPC::SRAW_rec:
13232 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13242 bool IsSignExtended =
13245 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13246 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13247 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13248 .
addReg(
MI.getOperand(3).getReg());
13249 MI.getOperand(3).setReg(ValueReg);
13253 if (Subtarget.hasPartwordAtomics())
13261 bool is64bit = Subtarget.isPPC64();
13262 bool isLittleEndian = Subtarget.isLittleEndian();
13263 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13274 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13276 F->insert(It, loopMBB);
13278 F->insert(It, loop2MBB);
13279 F->insert(It, exitMBB);
13285 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13288 Register PtrReg = RegInfo.createVirtualRegister(RC);
13289 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13291 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13292 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13293 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13294 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13295 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13296 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13297 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13298 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13299 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13300 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13303 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13330 if (ptrA != ZeroReg) {
13331 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13332 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13340 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13341 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13344 .
addImm(is8bit ? 28 : 27);
13345 if (!isLittleEndian)
13346 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13348 .
addImm(is8bit ? 24 : 16);
13350 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13355 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13365 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13369 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13374 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13378 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13381 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13388 Register SReg = RegInfo.createVirtualRegister(GPRC);
13389 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13393 unsigned ValueReg = SReg;
13394 unsigned CmpReg = Incr2Reg;
13395 if (CmpOpcode == PPC::CMPW) {
13396 ValueReg = RegInfo.createVirtualRegister(GPRC);
13397 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13400 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13401 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13403 ValueReg = ValueSReg;
13435 .
addImm(is8bit ? 24 : 16)
13456 Register DstReg =
MI.getOperand(0).getReg();
13458 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13463 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13464 "Invalid Pointer Size!");
13513 Register BufReg =
MI.getOperand(1).getReg();
13515 if (Subtarget.is64BitELFABI()) {
13528 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13530 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13533 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13556 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13559 if (Subtarget.isPPC64()) {
13577 TII->get(PPC::PHI), DstReg)
13581 MI.eraseFromParent();
13595 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13596 "Invalid Pointer Size!");
13599 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13602 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13603 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13617 Register BufReg =
MI.getOperand(0).getReg();
13622 if (PVT == MVT::i64) {
13634 if (PVT == MVT::i64) {
13646 if (PVT == MVT::i64) {
13658 if (PVT == MVT::i64) {
13670 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13680 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13683 MI.eraseFromParent();
13699 "Unexpected stack alignment");
13703 unsigned StackProbeSize =
13706 StackProbeSize &= ~(StackAlign - 1);
13707 return StackProbeSize ? StackProbeSize : StackAlign;
13719 const bool isPPC64 = Subtarget.isPPC64();
13751 MF->
insert(MBBIter, TestMBB);
13752 MF->
insert(MBBIter, BlockMBB);
13753 MF->
insert(MBBIter, TailMBB);
13758 Register DstReg =
MI.getOperand(0).getReg();
13759 Register NegSizeReg =
MI.getOperand(1).getReg();
13771 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13777 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13778 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13780 .
addDef(ActualNegSizeReg)
13782 .
add(
MI.getOperand(2))
13783 .
add(
MI.getOperand(3));
13789 .
addReg(ActualNegSizeReg);
13792 int64_t NegProbeSize = -(int64_t)ProbeSize;
13798 .
addImm(NegProbeSize >> 16);
13802 .
addImm(NegProbeSize & 0xFFFF);
13811 .
addReg(ActualNegSizeReg)
13820 .
addReg(ActualNegSizeReg);
13830 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13857 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13858 MaxCallFrameSizeReg)
13859 .
add(
MI.getOperand(2))
13860 .
add(
MI.getOperand(3));
13861 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13863 .
addReg(MaxCallFrameSizeReg);
13869 MBB->addSuccessor(TestMBB);
13872 MI.eraseFromParent();
13874 ++NumDynamicAllocaProbed;
13879 switch (
MI.getOpcode()) {
13880 case PPC::SELECT_CC_I4:
13881 case PPC::SELECT_CC_I8:
13882 case PPC::SELECT_CC_F4:
13883 case PPC::SELECT_CC_F8:
13884 case PPC::SELECT_CC_F16:
13885 case PPC::SELECT_CC_VRRC:
13886 case PPC::SELECT_CC_VSFRC:
13887 case PPC::SELECT_CC_VSSRC:
13888 case PPC::SELECT_CC_VSRC:
13889 case PPC::SELECT_CC_SPE4:
13890 case PPC::SELECT_CC_SPE:
13898 switch (
MI.getOpcode()) {
13899 case PPC::SELECT_I4:
13900 case PPC::SELECT_I8:
13901 case PPC::SELECT_F4:
13902 case PPC::SELECT_F8:
13903 case PPC::SELECT_F16:
13904 case PPC::SELECT_SPE:
13905 case PPC::SELECT_SPE4:
13906 case PPC::SELECT_VRRC:
13907 case PPC::SELECT_VSFRC:
13908 case PPC::SELECT_VSSRC:
13909 case PPC::SELECT_VSRC:
13919 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13920 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13921 if (Subtarget.is64BitELFABI() &&
13922 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13923 !Subtarget.isUsingPCRelativeCalls()) {
13935 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13936 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13938 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13939 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13953 if (Subtarget.hasISEL() &&
13954 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13955 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13956 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13958 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13959 MI.getOpcode() == PPC::SELECT_CC_I8)
13960 Cond.push_back(
MI.getOperand(4));
13963 Cond.push_back(
MI.getOperand(1));
13966 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13967 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13983 F->insert(It, copy0MBB);
13984 F->insert(It, sinkMBB);
13993 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14008 .
addReg(
MI.getOperand(1).getReg())
14011 unsigned SelectPred =
MI.getOperand(4).getImm();
14014 .
addReg(
MI.getOperand(1).getReg())
14031 .
addReg(
MI.getOperand(3).getReg())
14033 .
addReg(
MI.getOperand(2).getReg())
14035 }
else if (
MI.getOpcode() == PPC::ReadTB) {
14051 F->insert(It, readMBB);
14052 F->insert(It, sinkMBB);
14063 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14071 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14073 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14083 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
14085 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
14087 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
14089 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
14092 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
14094 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
14096 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
14098 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
14101 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
14103 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
14105 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
14107 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14110 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14112 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14114 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14116 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14119 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14121 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14123 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14125 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14128 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14130 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14132 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14134 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14137 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14139 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14141 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14143 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14146 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14148 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14150 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14152 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14155 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14157 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14159 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14161 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14164 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14166 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14168 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14170 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14173 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14175 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14177 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14179 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14181 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14182 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14183 (Subtarget.hasPartwordAtomics() &&
14184 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14185 (Subtarget.hasPartwordAtomics() &&
14186 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14187 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14189 auto LoadMnemonic = PPC::LDARX;
14190 auto StoreMnemonic = PPC::STDCX;
14191 switch (
MI.getOpcode()) {
14194 case PPC::ATOMIC_CMP_SWAP_I8:
14195 LoadMnemonic = PPC::LBARX;
14196 StoreMnemonic = PPC::STBCX;
14197 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14199 case PPC::ATOMIC_CMP_SWAP_I16:
14200 LoadMnemonic = PPC::LHARX;
14201 StoreMnemonic = PPC::STHCX;
14202 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14204 case PPC::ATOMIC_CMP_SWAP_I32:
14205 LoadMnemonic = PPC::LWARX;
14206 StoreMnemonic = PPC::STWCX;
14208 case PPC::ATOMIC_CMP_SWAP_I64:
14209 LoadMnemonic = PPC::LDARX;
14210 StoreMnemonic = PPC::STDCX;
14217 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14218 Register oldval =
MI.getOperand(3).getReg();
14219 Register newval =
MI.getOperand(4).getReg();
14225 F->insert(It, loop1MBB);
14226 F->insert(It, loop2MBB);
14227 F->insert(It, exitMBB);
14248 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14274 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14275 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14279 bool is64bit = Subtarget.isPPC64();
14280 bool isLittleEndian = Subtarget.isLittleEndian();
14281 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14286 Register oldval =
MI.getOperand(3).getReg();
14287 Register newval =
MI.getOperand(4).getReg();
14293 F->insert(It, loop1MBB);
14294 F->insert(It, loop2MBB);
14295 F->insert(It, exitMBB);
14302 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14305 Register PtrReg = RegInfo.createVirtualRegister(RC);
14306 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14308 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14309 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14310 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14311 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14312 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14313 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14314 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14315 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14316 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14317 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14318 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14320 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14321 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14322 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14353 if (ptrA != ZeroReg) {
14354 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14355 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14364 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14365 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14368 .
addImm(is8bit ? 28 : 27);
14369 if (!isLittleEndian)
14370 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14372 .
addImm(is8bit ? 24 : 16);
14374 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14379 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14384 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14387 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14394 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14398 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14401 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14404 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14409 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14426 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14450 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14460 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14475 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14483 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14484 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14485 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14486 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14487 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14488 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14491 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14492 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14495 Register Dest = RegInfo.createVirtualRegister(
14496 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14500 .
addReg(
MI.getOperand(1).getReg())
14503 MI.getOperand(0).getReg())
14504 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14505 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14508 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14511 MI.getOperand(0).getReg())
14513 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14515 unsigned Imm =
MI.getOperand(1).getImm();
14518 MI.getOperand(0).getReg())
14520 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14522 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14526 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14528 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14539 unsigned Mode =
MI.getOperand(1).getImm();
14540 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14544 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14547 }
else if (
MI.getOpcode() == PPC::SETRND) {
14555 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14556 if (Subtarget.hasDirectMove()) {
14557 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14561 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14564 if (RC == &PPC::F8RCRegClass) {
14566 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14567 "Unsupported RegClass.");
14569 StoreOp = PPC::STFD;
14573 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14574 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14575 "Unsupported RegClass.");
14608 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14611 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14623 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14625 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14627 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14628 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14633 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14634 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14639 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14640 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14646 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14647 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14656 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14660 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14662 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14664 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14667 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14673 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14674 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14676 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14683 .
addUse(Src, {}, PPC::sub_gp8_x1);
14686 .
addUse(Src, {}, PPC::sub_gp8_x0);
14687 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14688 MI.getOpcode() == PPC::STQX_PSEUDO) {
14694 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14700 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14701 :
TII->get(PPC::STQ))
14705 }
else if (
MI.getOpcode() == PPC::LWAT_PSEUDO ||
14706 MI.getOpcode() == PPC::LDAT_PSEUDO) {
14708 Register DstReg =
MI.getOperand(0).getReg();
14709 Register PtrReg =
MI.getOperand(1).getReg();
14710 Register ValReg =
MI.getOperand(2).getReg();
14711 unsigned FC =
MI.getOperand(3).getImm();
14712 bool IsLwat =
MI.getOpcode() == PPC::LWAT_PSEUDO;
14715 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
14723 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
14726 .
addImm(PPC::sub_gp8_x0)
14728 .
addImm(PPC::sub_gp8_x1);
14731 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
14737 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14740 .
addReg(Result64, {}, PPC::sub_32);
14744 }
else if (
MI.getOpcode() == PPC::LWAT_COND_PSEUDO ||
14745 MI.getOpcode() == PPC::LDAT_COND_PSEUDO) {
14747 Register DstReg =
MI.getOperand(0).getReg();
14748 Register PtrReg =
MI.getOperand(1).getReg();
14749 unsigned FC =
MI.getOperand(2).getImm();
14750 bool IsLwat_Cond =
MI.getOpcode() == PPC::LWAT_COND_PSEUDO;
14753 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), Pair);
14756 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat_Cond ? PPC::LWAT : PPC::LDAT),
14763 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14766 .
addReg(Result64, {}, PPC::sub_32);
14774 MI.eraseFromParent();
14787 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14790 return RefinementSteps;
14797 EVT VT =
Op.getValueType();
14800 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14824PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14827 EVT VT =
Op.getValueType();
14828 if (VT != MVT::f64 &&
14829 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14832 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14836 int Enabled,
int &RefinementSteps,
14837 bool &UseOneConstNR,
14838 bool Reciprocal)
const {
14840 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14841 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14842 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14843 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14849 UseOneConstNR = !Subtarget.needsTwoConstNR();
14850 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14857 int &RefinementSteps)
const {
14859 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14860 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14861 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14862 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14865 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14881 switch (Subtarget.getCPUDirective()) {
14908 unsigned Bytes,
int Dist,
14922 if (FS != BFS || FS != (
int)Bytes)
return false;
14927 int64_t Offset1 = 0, Offset2 = 0;
14930 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14940 if (isGA1 && isGA2 && GV1 == GV2)
14941 return Offset1 == (Offset2 + Dist*Bytes);
14948 unsigned Bytes,
int Dist,
14951 EVT VT = LS->getMemoryVT();
14958 switch (
N->getConstantOperandVal(1)) {
14959 default:
return false;
14960 case Intrinsic::ppc_altivec_lvx:
14961 case Intrinsic::ppc_altivec_lvxl:
14962 case Intrinsic::ppc_vsx_lxvw4x:
14963 case Intrinsic::ppc_vsx_lxvw4x_be:
14966 case Intrinsic::ppc_vsx_lxvd2x:
14967 case Intrinsic::ppc_vsx_lxvd2x_be:
14970 case Intrinsic::ppc_altivec_lvebx:
14973 case Intrinsic::ppc_altivec_lvehx:
14976 case Intrinsic::ppc_altivec_lvewx:
14986 switch (
N->getConstantOperandVal(1)) {
14987 default:
return false;
14988 case Intrinsic::ppc_altivec_stvx:
14989 case Intrinsic::ppc_altivec_stvxl:
14990 case Intrinsic::ppc_vsx_stxvw4x:
14993 case Intrinsic::ppc_vsx_stxvd2x:
14996 case Intrinsic::ppc_vsx_stxvw4x_be:
14999 case Intrinsic::ppc_vsx_stxvd2x_be:
15002 case Intrinsic::ppc_altivec_stvebx:
15005 case Intrinsic::ppc_altivec_stvehx:
15008 case Intrinsic::ppc_altivec_stvewx:
15025 SDValue Chain = LD->getChain();
15026 EVT VT = LD->getMemoryVT();
15035 while (!Queue.empty()) {
15036 SDNode *ChainNext = Queue.pop_back_val();
15037 if (!Visited.
insert(ChainNext).second)
15044 if (!Visited.
count(ChainLD->getChain().getNode()))
15045 Queue.push_back(ChainLD->getChain().getNode());
15047 for (
const SDUse &O : ChainNext->
ops())
15048 if (!Visited.
count(O.getNode()))
15049 Queue.push_back(O.getNode());
15051 LoadRoots.
insert(ChainNext);
15062 for (
SDNode *
I : LoadRoots) {
15063 Queue.push_back(
I);
15065 while (!Queue.empty()) {
15066 SDNode *LoadRoot = Queue.pop_back_val();
15067 if (!Visited.
insert(LoadRoot).second)
15079 Queue.push_back(U);
15112 auto Final = Shifted;
15123 DAGCombinerInfo &DCI)
const {
15126 SelectionDAG &DAG = DCI.DAG;
15131 if (!DCI.isAfterLegalizeDAG())
15136 for (
const SDNode *U :
N->users())
15141 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15145 if (OpSize <
Size) {
15163 DAGCombinerInfo &DCI)
const {
15164 SelectionDAG &DAG = DCI.DAG;
15167 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15178 N->getValueType(0) != MVT::i1)
15181 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15182 N->getOperand(0).getValueType() != MVT::i64)
15192 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15203 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15226 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15227 N->getOperand(0).getOpcode() !=
ISD::OR &&
15228 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15238 N->getOperand(1).getOpcode() !=
ISD::AND &&
15239 N->getOperand(1).getOpcode() !=
ISD::OR &&
15240 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15251 SmallPtrSet<SDNode *, 16> Visited;
15253 for (
unsigned i = 0; i < 2; ++i) {
15257 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15269 while (!BinOps.
empty()) {
15277 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15311 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15315 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15316 if (User !=
N && !Visited.
count(User))
15325 if (
User->getOperand(0) == Inputs[i])
15328 if (
User->getOperand(0) == Inputs[i] ||
15329 User->getOperand(1) == Inputs[i])
15335 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15336 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15337 if (User !=
N && !Visited.
count(User))
15346 if (
User->getOperand(0) == PromOps[i])
15349 if (
User->getOperand(0) == PromOps[i] ||
15350 User->getOperand(1) == PromOps[i])
15357 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15366 std::list<HandleSDNode> PromOpHandles;
15367 for (
auto &PromOp : PromOps)
15368 PromOpHandles.emplace_back(PromOp);
15375 while (!PromOpHandles.empty()) {
15376 SDValue PromOp = PromOpHandles.back().getValue();
15377 PromOpHandles.pop_back();
15386 PromOpHandles.emplace_front(PromOp);
15400 default:
C = 0;
break;
15413 PromOpHandles.emplace_front(PromOp);
15420 for (
unsigned i = 0; i < 2; ++i)
15430 return N->getOperand(0);
15438 DAGCombinerInfo &DCI)
const {
15439 SelectionDAG &DAG = DCI.DAG;
15456 if (
N->getValueType(0) != MVT::i32 &&
15457 N->getValueType(0) != MVT::i64)
15460 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15461 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15464 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15465 N->getOperand(0).getOpcode() !=
ISD::OR &&
15466 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15473 SmallPtrSet<SDNode *, 16> Visited;
15477 while (!BinOps.
empty()) {
15485 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15511 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15516 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15521 if (User !=
N && !Visited.
count(User))
15527 if (
User->getOperand(0) == Inputs[i])
15528 SelectTruncOp[0].
insert(std::make_pair(User,
15529 User->getOperand(0).getValueType()));
15531 if (
User->getOperand(0) == Inputs[i])
15532 SelectTruncOp[0].
insert(std::make_pair(User,
15533 User->getOperand(0).getValueType()));
15534 if (
User->getOperand(1) == Inputs[i])
15535 SelectTruncOp[1].
insert(std::make_pair(User,
15536 User->getOperand(1).getValueType()));
15541 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15543 if (User !=
N && !Visited.
count(User))
15549 if (
User->getOperand(0) == PromOps[i])
15550 SelectTruncOp[0].
insert(std::make_pair(User,
15551 User->getOperand(0).getValueType()));
15553 if (
User->getOperand(0) == PromOps[i])
15554 SelectTruncOp[0].
insert(std::make_pair(User,
15555 User->getOperand(0).getValueType()));
15556 if (
User->getOperand(1) == PromOps[i])
15557 SelectTruncOp[1].
insert(std::make_pair(User,
15558 User->getOperand(1).getValueType()));
15563 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15564 bool ReallyNeedsExt =
false;
15568 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15573 Inputs[i].getOperand(0).getValueSizeInBits();
15574 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15579 OpBits-PromBits))) ||
15582 (OpBits-(PromBits-1)))) {
15583 ReallyNeedsExt =
true;
15591 std::list<HandleSDNode> PromOpHandles;
15592 for (
auto &PromOp : PromOps)
15593 PromOpHandles.emplace_back(PromOp);
15597 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15604 SDValue InSrc = Inputs[i].getOperand(0);
15622 while (!PromOpHandles.empty()) {
15624 PromOpHandles.pop_back();
15628 default:
C = 0;
break;
15641 PromOpHandles.emplace_front(PromOp);
15651 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15653 PromOpHandles.emplace_front(PromOp);
15661 for (
unsigned i = 0; i < 2; ++i) {
15679 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15680 if (SI0 != SelectTruncOp[0].
end())
15682 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15683 if (SI1 != SelectTruncOp[1].
end())
15692 if (!ReallyNeedsExt)
15693 return N->getOperand(0);
15700 N->getValueSizeInBits(0), PromBits),
15701 dl,
N->getValueType(0)));
15704 "Invalid extension type");
15707 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15717 auto isValidForConvert = [](
SDValue &Operand) {
15736 if (LoadNode->isVolatile())
15757 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15767 "CC mus be ISD::SETNE or ISD::SETEQ");
15769 auto getV16i8Load = [&](
const SDValue &Operand) {
15777 DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15778 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15819 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15820 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15823 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15826 IntrID, CRSel, LHSVec, RHSVec);
15829 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15847 auto IsAndWithOne = [](
SDValue &V) {
15858 auto IsCompareWithZero = [](
SDValue &V) {
15865 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15866 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15883 auto MakeXor1 = [&](
SDValue V) {
15884 EVT VT = V.getValueType();
15891 return MakeXor1(
LHS);
15894 return MakeXor1(
RHS);
15900 DAGCombinerInfo &DCI)
const {
15902 "Should be called with a SETCC node");
15924 SelectionDAG &DAG = DCI.DAG;
15925 EVT VT =
N->getValueType(0);
15926 EVT OpVT =
LHS.getValueType();
15948 return DAGCombineTruncBoolExt(
N, DCI);
15955 Op.getValueType() == MVT::f64;
15967combineElementTruncationToVectorTruncation(
SDNode *
N,
15968 DAGCombinerInfo &DCI)
const {
15970 "Should be called with a BUILD_VECTOR node");
15972 SelectionDAG &DAG = DCI.DAG;
15975 SDValue FirstInput =
N->getOperand(0);
15977 "The input operand must be an fp-to-int conversion.");
15982 if (FirstConversion == PPCISD::FCTIDZ ||
15983 FirstConversion == PPCISD::FCTIDUZ ||
15984 FirstConversion == PPCISD::FCTIWZ ||
15985 FirstConversion == PPCISD::FCTIWUZ) {
15986 bool IsSplat =
true;
15987 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
15988 FirstConversion == PPCISD::FCTIWUZ;
15991 EVT TargetVT =
N->getValueType(0);
15992 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15993 SDValue NextOp =
N->getOperand(i);
15994 if (NextOp.
getOpcode() != PPCISD::MFVSR)
15997 if (NextConversion != FirstConversion)
16005 if (
N->getOperand(i) != FirstInput)
16016 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16017 SDValue In =
N->getOperand(i).getOperand(0);
16027 Ops.push_back(Trunc);
16030 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16034 if (FirstConversion == PPCISD::FCTIDZ ||
16035 FirstConversion == PPCISD::FCTIWZ)
16040 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16042 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16060 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16064 if (FullVal == BasePattern)
16065 return std::make_tuple(Uim,
uint8_t{0});
16068 if (FullVal ==
APInt(128, 1))
16069 return std::make_tuple(Uim,
uint8_t{127});
16071 return std::nullopt;
16091 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16095 EVT VT =
Op.getValueType();
16096 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16110 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16120 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16124 uint64_t ElemValue =
C->getZExtValue();
16128 ElemValue &= ((1ULL << ElemBits) - 1);
16132 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16135 APInt ElemAPInt(128, ElemValue);
16136 ElemAPInt <<= BitPos;
16139 FullVal |= ElemAPInt;
16146 const auto &[Uim, ShiftAmount] = *UIMOpt;
16150 if (ShiftAmount == 0) {
16155 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16156 LxvkqInstr.
dump());
16160 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16172 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16175 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16191 "Should be called with a BUILD_VECTOR node");
16196 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16199 bool InputsAreConsecutiveLoads =
true;
16200 bool InputsAreReverseConsecutive =
true;
16201 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16202 SDValue FirstInput =
N->getOperand(0);
16203 bool IsRoundOfExtLoad =
false;
16213 N->getNumOperands() == 1)
16216 if (!IsRoundOfExtLoad)
16221 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16223 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16226 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16232 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16243 InputsAreConsecutiveLoads =
false;
16245 InputsAreReverseConsecutive =
false;
16248 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16253 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16254 "The loads cannot be both consecutive and reverse consecutive.");
16258 if (InputsAreConsecutiveLoads) {
16259 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16263 ReturnSDVal = WideLoad;
16264 }
else if (InputsAreReverseConsecutive) {
16266 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16271 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16279 for (
auto *LD : InputLoads)
16281 return ReturnSDVal;
16292 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16298 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16300 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16302 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16303 CorrectElems = CorrectElems >> 8;
16304 Elems = Elems >> 8;
16311 EVT VT =
N->getValueType(0);
16315 Input.getValueType().getVectorElementType(),
16349 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16375 Elems = Elems << 8;
16384 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16385 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16392 int TgtElemArrayIdx;
16393 int InputSize =
Input.getValueType().getScalarSizeInBits();
16394 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16395 if (InputSize + OutputSize == 40)
16396 TgtElemArrayIdx = 0;
16397 else if (InputSize + OutputSize == 72)
16398 TgtElemArrayIdx = 1;
16399 else if (InputSize + OutputSize == 48)
16400 TgtElemArrayIdx = 2;
16401 else if (InputSize + OutputSize == 80)
16402 TgtElemArrayIdx = 3;
16403 else if (InputSize + OutputSize == 96)
16404 TgtElemArrayIdx = 4;
16408 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16410 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16411 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16412 if (Elems != CorrectElems) {
16428 if (
N->getValueType(0) != MVT::v1i128)
16431 SDValue Operand =
N->getOperand(0);
16438 EVT MemoryType = LD->getMemoryVT();
16442 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16443 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16446 if (!ValidLDType ||
16452 LD->getChain(), LD->getBasePtr(),
16456 DAG.
getVTList(MVT::v1i128, MVT::Other),
16457 LoadOps, MemoryType, LD->getMemOperand());
16461 DAGCombinerInfo &DCI)
const {
16463 "Should be called with a BUILD_VECTOR node");
16465 SelectionDAG &DAG = DCI.DAG;
16468 if (!Subtarget.hasVSX())
16475 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16476 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16491 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16500 if (Subtarget.isISA3_1()) {
16506 if (
N->getValueType(0) != MVT::v2f64)
16517 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16528 if (!Ext1Op || !Ext2Op)
16537 if (FirstElem == 0 && SecondElem == 1)
16538 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16539 else if (FirstElem == 2 && SecondElem == 3)
16540 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16546 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16547 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16552 DAGCombinerInfo &DCI)
const {
16555 "Need an int -> FP conversion node here");
16560 SelectionDAG &DAG = DCI.DAG;
16566 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16568 if (!
Op.getOperand(0).getValueType().isSimple())
16570 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16571 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16574 SDValue FirstOperand(
Op.getOperand(0));
16575 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16576 (FirstOperand.getValueType() == MVT::i8 ||
16577 FirstOperand.getValueType() == MVT::i16);
16578 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16580 bool DstDouble =
Op.getValueType() == MVT::f64;
16581 unsigned ConvOp =
Signed ?
16582 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16583 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16588 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16591 Ops, MVT::i8, LDN->getMemOperand());
16596 SDValue ExtOps[] = { Ld, WidthConst };
16598 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16600 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16608 if (
Op.getOperand(0).getValueType() == MVT::i32)
16612 "UINT_TO_FP is supported only with FPCVT");
16616 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16621 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16628 Subtarget.hasFPCVT()) ||
16630 SDValue Src =
Op.getOperand(0).getOperand(0);
16631 if (Src.getValueType() == MVT::f32) {
16633 DCI.AddToWorklist(Src.getNode());
16634 }
else if (Src.getValueType() != MVT::f64) {
16646 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16649 DCI.AddToWorklist(
FP.getNode());
16673 switch (
N->getOpcode()) {
16678 Chain = LD->getChain();
16679 Base = LD->getBasePtr();
16680 MMO = LD->getMemOperand();
16699 MVT VecTy =
N->getValueType(0).getSimpleVT();
16707 Chain = Load.getValue(1);
16709 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16713 if (VecTy != MVT::v2f64) {
16740 switch (
N->getOpcode()) {
16745 Chain = ST->getChain();
16746 Base = ST->getBasePtr();
16747 MMO = ST->getMemOperand();
16767 SDValue Src =
N->getOperand(SrcOpnd);
16768 MVT VecTy = Src.getValueType().getSimpleVT();
16771 if (VecTy != MVT::v2f64) {
16777 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16783 StoreOps, VecTy, MMO);
16790 DAGCombinerInfo &DCI)
const {
16793 unsigned Opcode =
N->getOperand(1).getOpcode();
16795 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16799 &&
"Not a FP_TO_INT Instruction!");
16801 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16802 EVT Op1VT =
N->getOperand(1).getValueType();
16805 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16809 bool ValidTypeForStoreFltAsInt =
16810 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16811 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16814 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16817 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16825 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16840 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16841 for (
int i = 1, e = Mask.size(); i < e; i++) {
16842 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16844 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16846 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16857 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16858 FirstOp =
Op.getOperand(i);
16864 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16865 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16875 Op =
Op.getOperand(0);
16891 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16892 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16894 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16896 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16897 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16898 int Idx = ShuffV[
I];
16899 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16900 ShuffV[
I] += LHSEltFixup;
16901 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16902 ShuffV[
I] += RHSEltFixup;
16913 SDLoc dl(OrigSToV);
16916 "Expecting a SCALAR_TO_VECTOR here");
16929 "Cannot produce a permuted scalar_to_vector for one element vector");
16931 unsigned ResultInElt = NumElts / 2;
16937 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
16942 int HalfVec,
int LHSLastElementDefined,
16943 int RHSLastElementDefined) {
16944 for (
int Index : ShuffV) {
16948 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16949 (Index > LHSLastElementDefined))
16952 if ((RHSLastElementDefined >= 0) &&
16953 (Index > HalfVec + RHSLastElementDefined))
16960 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16961 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16977 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16978 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16981 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16982 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16983 return SToVPermuted;
17003 int NumElts =
LHS.getValueType().getVectorNumElements();
17006 bool IsLittleEndian = Subtarget.isLittleEndian();
17013 if (!Subtarget.hasDirectMove())
17033 SmallVector<int, 16> ShuffV(Mask);
17036 if (SToVLHS || SToVRHS) {
17039 int ShuffleNumElts = ShuffV.
size();
17040 int HalfVec = ShuffleNumElts / 2;
17046 unsigned LHSNumValidElts = HalfVec;
17047 unsigned RHSNumValidElts = HalfVec;
17052 int LHSFirstElt = 0;
17053 int RHSFirstElt = ShuffleNumElts;
17054 int LHSLastElt = -1;
17055 int RHSLastElt = -1;
17063 int LHSScalarSize = 0;
17064 int RHSScalarSize = 0;
17067 if (!IsLittleEndian && LHSScalarSize >= 64)
17072 if (!IsLittleEndian && RHSScalarSize >= 64)
17075 if (LHSScalarSize != 0)
17077 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17078 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17079 if (RHSScalarSize != 0)
17081 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17082 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17093 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17094 LHSNumValidElts, RHSNumValidElts, Subtarget);
17120 if (IsLittleEndian) {
17123 if (Mask[0] < NumElts)
17124 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17128 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17133 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17137 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17142 if (Mask[0] < NumElts)
17143 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17147 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17152 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17156 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17166 if (IsLittleEndian)
17175 DAGCombinerInfo &DCI)
const {
17177 "Not a reverse memop pattern!");
17179 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17182 auto I =
Mask.rbegin();
17183 auto E =
Mask.rend();
17185 for (;
I !=
E; ++
I) {
17193 SelectionDAG &DAG = DCI.DAG;
17196 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17202 if (!Subtarget.hasP9Vector())
17205 if(!IsElementReverse(SVN))
17212 for (SDUse &Use : LSBase->
uses())
17213 if (
Use.getResNo() == 0 &&
17220 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17235 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17244 if (IntrinsicID == Intrinsic::ppc_stdcx)
17246 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17248 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17250 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17259 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17263 if (
LHS->getOpcode() == PPCISD::ADDE &&
17315 auto isZeroOrOne = [=](
SDValue &V) {
17317 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17322 if (!isZeroOrOne(NonNullConstant))
17332 EVT VType =
N->getValueType(0);
17336 return NewNonNullConstant;
17355 EVT XorVT =
N->getValueType(0);
17356 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17364 if (!XorConst || !XorConst->
isOne()) {
17366 if (!XorConst || !XorConst->
isOne())
17373 if (!
LHS.hasOneUse())
17381 SelectNode =
LHS.getOperand(0);
17395 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17405 if (!ConstOp1 || !ConstOp2)
17409 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17418 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17420 bool ConstOp1IsOne = ConstOp1->
isOne();
17423 {SelectNode.getOperand(0),
17424 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17425 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17426 SelectNode.getOperand(3)}),
17434 switch (
N->getOpcode()) {
17437 return combineADD(
N, DCI);
17469 return combineSHL(
N, DCI);
17471 return combineSRA(
N, DCI);
17473 return combineSRL(
N, DCI);
17475 return combineMUL(
N, DCI);
17477 case PPCISD::FNMSUB:
17478 return combineFMALike(
N, DCI);
17481 return N->getOperand(0);
17485 return N->getOperand(0);
17491 return N->getOperand(0);
17500 return DAGCombineExtBoolTrunc(
N, DCI);
17502 return combineTRUNCATE(
N, DCI);
17504 if (
SDValue CSCC = combineSetCC(
N, DCI))
17508 return DAGCombineTruncBoolExt(
N, DCI);
17511 return combineFPToIntToFP(
N, DCI);
17520 EVT Op1VT =
N->getOperand(1).getValueType();
17521 unsigned Opcode =
N->getOperand(1).getOpcode();
17525 SDValue Val = combineStoreFPToInt(
N, DCI);
17539 N->getOperand(1).getNode()->hasOneUse() &&
17540 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17541 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17549 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17556 if (Op1VT.
bitsGT(mVT)) {
17561 if (Op1VT == MVT::i64)
17566 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17586 ST->getBasePtr(), ST->getOffset(), MemVT,
17587 ST->getMemOperand(), ST->getAddressingMode(),
17591 return ST->isUnindexed()
17600 if (Subtarget.needsSwapsForVSXMemOps() &&
17601 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17602 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17609 EVT VT = LD->getValueType(0);
17615 if (Subtarget.needsSwapsForVSXMemOps() &&
17616 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17617 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17628 auto ReplaceTwoFloatLoad = [&]() {
17629 if (VT != MVT::i64)
17644 if (!LD->hasNUsesOfValue(2, 0))
17647 auto UI = LD->user_begin();
17648 while (UI.getUse().getResNo() != 0) ++UI;
17650 while (UI.getUse().getResNo() != 0) ++UI;
17651 SDNode *RightShift = *UI;
17659 if (RightShift->getOpcode() !=
ISD::SRL ||
17661 RightShift->getConstantOperandVal(1) != 32 ||
17662 !RightShift->hasOneUse())
17665 SDNode *Trunc2 = *RightShift->user_begin();
17675 Bitcast->getValueType(0) != MVT::f32)
17681 if (Subtarget.isLittleEndian())
17687 SDValue BasePtr = LD->getBasePtr();
17688 if (LD->isIndexed()) {
17690 "Non-pre-inc AM on PPC?");
17698 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17699 LD->getPointerInfo(), LD->getAlign(),
17700 MMOFlags, LD->getAAInfo());
17706 LD->getPointerInfo().getWithOffset(4),
17709 if (LD->isIndexed()) {
17723 if (ReplaceTwoFloatLoad())
17726 EVT MemVT = LD->getMemoryVT();
17729 if (LD->isUnindexed() && VT.
isVector() &&
17732 !Subtarget.hasP8Vector() &&
17733 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17734 VT == MVT::v4f32))) &&
17735 LD->getAlign() < ABIAlignment) {
17737 SDValue Chain = LD->getChain();
17738 SDValue Ptr = LD->getBasePtr();
17739 bool isLittleEndian = Subtarget.isLittleEndian();
17766 MVT PermCntlTy, PermTy, LDTy;
17767 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17768 : Intrinsic::ppc_altivec_lvsl;
17769 IntrLD = Intrinsic::ppc_altivec_lvx;
17770 IntrPerm = Intrinsic::ppc_altivec_vperm;
17771 PermCntlTy = MVT::v16i8;
17772 PermTy = MVT::v4i32;
17791 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
17795 BaseLoadOps, LDTy, BaseMMO);
17804 int IncValue = IncOffset;
17821 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
17825 ExtraLoadOps, LDTy, ExtraMMO);
17836 if (isLittleEndian)
17838 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17841 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17844 Perm = Subtarget.hasAltivec()
17859 bool isLittleEndian = Subtarget.isLittleEndian();
17860 unsigned IID =
N->getConstantOperandVal(0);
17861 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17862 : Intrinsic::ppc_altivec_lvsl);
17863 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17870 .zext(
Add.getScalarValueSizeInBits()))) {
17871 SDNode *BasePtr =
Add->getOperand(0).getNode();
17872 for (
SDNode *U : BasePtr->users()) {
17874 U->getConstantOperandVal(0) == IID) {
17885 SDNode *BasePtr =
Add->getOperand(0).getNode();
17886 for (
SDNode *U : BasePtr->users()) {
17889 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17895 V->getConstantOperandVal(0) == IID) {
17907 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17908 IID == Intrinsic::ppc_altivec_vmaxsh ||
17909 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17940 switch (
N->getConstantOperandVal(1)) {
17943 case Intrinsic::ppc_altivec_vsum4sbs:
17944 case Intrinsic::ppc_altivec_vsum4shs:
17945 case Intrinsic::ppc_altivec_vsum4ubs: {
17952 APInt APSplatBits, APSplatUndef;
17953 unsigned SplatBitSize;
17956 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17957 !Subtarget.isLittleEndian());
17959 if (BVNIsConstantSplat && APSplatBits == 0)
17964 case Intrinsic::ppc_vsx_lxvw4x:
17965 case Intrinsic::ppc_vsx_lxvd2x:
17968 if (Subtarget.needsSwapsForVSXMemOps())
17976 if (Subtarget.needsSwapsForVSXMemOps()) {
17977 switch (
N->getConstantOperandVal(1)) {
17980 case Intrinsic::ppc_vsx_stxvw4x:
17981 case Intrinsic::ppc_vsx_stxvd2x:
17990 bool Is64BitBswapOn64BitTgt =
17991 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17993 N->getOperand(0).hasOneUse();
17994 if (IsSingleUseNormalLd &&
17995 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17996 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18007 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18008 MVT::i64 : MVT::i32, MVT::Other),
18009 Ops, LD->getMemoryVT(), LD->getMemOperand());
18013 if (
N->getValueType(0) == MVT::i16)
18030 !IsSingleUseNormalLd)
18035 if (!LD->isSimple())
18037 SDValue BasePtr = LD->getBasePtr();
18039 LD->getPointerInfo(), LD->getAlign());
18044 LD->getMemOperand(), 4, 4);
18048 if (Subtarget.isLittleEndian())
18054 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18063 if (!
N->getOperand(0).hasOneUse() &&
18064 !
N->getOperand(1).hasOneUse() &&
18065 !
N->getOperand(2).hasOneUse()) {
18068 SDNode *VCMPrecNode =
nullptr;
18070 SDNode *LHSN =
N->getOperand(0).getNode();
18072 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18076 VCMPrecNode =
User;
18088 SDNode *FlagUser =
nullptr;
18090 FlagUser ==
nullptr; ++UI) {
18091 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18104 return SDValue(VCMPrecNode, 0);
18115 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18126 auto RHSAPInt = RHS->getAsAPIntVal();
18127 if (!RHSAPInt.isIntN(64))
18130 unsigned Val = RHSAPInt.getZExtValue();
18131 auto isImpossibleCompare = [&]() {
18134 if (Val != 0 && Val != 1) {
18136 return N->getOperand(0);
18139 N->getOperand(0),
N->getOperand(4));
18144 unsigned StoreWidth = 0;
18147 if (
SDValue Impossible = isImpossibleCompare())
18159 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18163 PPCISD::STORE_COND, dl,
18165 MemNode->getMemoryVT(), MemNode->getMemOperand());
18169 if (
N->getOperand(0) == LHS.getValue(1))
18180 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18182 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18188 assert(isDot &&
"Can't compare against a vector result!");
18190 if (
SDValue Impossible = isImpossibleCompare())
18193 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18200 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18205 switch (LHS.getConstantOperandVal(1)) {
18221 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18224 N->getOperand(4), CompNode.
getValue(1));
18229 return DAGCombineBuildVector(
N, DCI);
18234 return DAGCombineBitcast(
N, DCI);
18245 EVT VT =
N->getValueType(0);
18246 if (VT == MVT::i64 && !Subtarget.isPPC64())
18248 if ((VT != MVT::i32 && VT != MVT::i64) ||
18256 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18276 const APInt &DemandedElts,
18278 unsigned Depth)
const {
18280 switch (
Op.getOpcode()) {
18282 case PPCISD::LBRX: {
18285 Known.
Zero = 0xFFFF0000;
18288 case PPCISD::ADDE: {
18289 if (
Op.getResNo() == 0) {
18294 Known.
Zero = ~1ULL;
18299 switch (
Op.getConstantOperandVal(0)) {
18301 case Intrinsic::ppc_altivec_vcmpbfp_p:
18302 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18303 case Intrinsic::ppc_altivec_vcmpequb_p:
18304 case Intrinsic::ppc_altivec_vcmpequh_p:
18305 case Intrinsic::ppc_altivec_vcmpequw_p:
18306 case Intrinsic::ppc_altivec_vcmpequd_p:
18307 case Intrinsic::ppc_altivec_vcmpequq_p:
18308 case Intrinsic::ppc_altivec_vcmpgefp_p:
18309 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18310 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18311 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18312 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18313 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18314 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18315 case Intrinsic::ppc_altivec_vcmpgtub_p:
18316 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18317 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18318 case Intrinsic::ppc_altivec_vcmpgtud_p:
18319 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18326 switch (
Op.getConstantOperandVal(1)) {
18329 case Intrinsic::ppc_load2r:
18331 Known.
Zero = 0xFFFF0000;
18340 switch (Subtarget.getCPUDirective()) {
18362 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18371 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18373 LoopSize +=
TII->getInstSizeInBytes(J);
18378 if (LoopSize > 16 && LoopSize <= 32)
18392 if (Constraint.
size() == 1) {
18393 switch (Constraint[0]) {
18411 }
else if (Constraint ==
"wc") {
18413 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18414 Constraint ==
"wf" || Constraint ==
"ws" ||
18415 Constraint ==
"wi" || Constraint ==
"ww") {
18428 Value *CallOperandVal =
info.CallOperandVal;
18431 if (!CallOperandVal)
18438 else if ((
StringRef(constraint) ==
"wa" ||
18450 switch (*constraint) {
18480std::pair<unsigned, const TargetRegisterClass *>
18484 if (Constraint.
size() == 1) {
18486 switch (Constraint[0]) {
18488 if (VT == MVT::i64 && Subtarget.isPPC64())
18489 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18490 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18492 if (VT == MVT::i64 && Subtarget.isPPC64())
18493 return std::make_pair(0U, &PPC::G8RCRegClass);
18494 return std::make_pair(0U, &PPC::GPRCRegClass);
18500 if (Subtarget.hasSPE()) {
18501 if (VT == MVT::f32 || VT == MVT::i32)
18502 return std::make_pair(0U, &PPC::GPRCRegClass);
18503 if (VT == MVT::f64 || VT == MVT::i64)
18504 return std::make_pair(0U, &PPC::SPERCRegClass);
18506 if (VT == MVT::f32 || VT == MVT::i32)
18507 return std::make_pair(0U, &PPC::F4RCRegClass);
18508 if (VT == MVT::f64 || VT == MVT::i64)
18509 return std::make_pair(0U, &PPC::F8RCRegClass);
18513 if (Subtarget.hasAltivec() && VT.
isVector())
18514 return std::make_pair(0U, &PPC::VRRCRegClass);
18515 else if (Subtarget.hasVSX())
18517 return std::make_pair(0U, &PPC::VFRCRegClass);
18520 return std::make_pair(0U, &PPC::CRRCRegClass);
18522 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18524 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18525 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18526 Constraint ==
"wf" || Constraint ==
"wi") &&
18527 Subtarget.hasVSX()) {
18531 return std::make_pair(0U, &PPC::VSRCRegClass);
18532 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18533 return std::make_pair(0U, &PPC::VSSRCRegClass);
18534 return std::make_pair(0U, &PPC::VSFRCRegClass);
18535 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18536 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18537 return std::make_pair(0U, &PPC::VSSRCRegClass);
18539 return std::make_pair(0U, &PPC::VSFRCRegClass);
18540 }
else if (Constraint ==
"lr") {
18541 if (VT == MVT::i64)
18542 return std::make_pair(0U, &PPC::LR8RCRegClass);
18544 return std::make_pair(0U, &PPC::LRRCRegClass);
18549 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18553 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18554 int VSNum = atoi(Constraint.
data() + 3);
18555 assert(VSNum >= 0 && VSNum <= 63 &&
18556 "Attempted to access a vsr out of range");
18558 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18559 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18564 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18565 int RegNum = atoi(Constraint.
data() + 2);
18566 if (RegNum > 31 || RegNum < 0)
18568 if (VT == MVT::f32 || VT == MVT::i32)
18569 return Subtarget.hasSPE()
18570 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18571 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18572 if (VT == MVT::f64 || VT == MVT::i64)
18573 return Subtarget.hasSPE()
18574 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18575 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18579 std::pair<unsigned, const TargetRegisterClass *> R =
18588 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18589 PPC::GPRCRegClass.contains(R.first))
18590 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18591 PPC::sub_32, &PPC::G8RCRegClass),
18592 &PPC::G8RCRegClass);
18595 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18596 R.first = PPC::CR0;
18597 R.second = &PPC::CRRCRegClass;
18601 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18602 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18603 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18604 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18605 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18606 "default AIX AltiVec ABI and cannot be used\n";
18616 std::vector<SDValue> &
Ops,
18621 if (Constraint.
size() > 1)
18624 char Letter = Constraint[0];
18639 EVT TCVT = MVT::i64;
18680 if (Result.getNode()) {
18681 Ops.push_back(Result);
18692 if (
I.getNumOperands() <= 1)
18696 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18697 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18698 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18701 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18717 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18729 switch (AM.
Scale) {
18757 unsigned Depth =
Op.getConstantOperandVal(0);
18781 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18789 unsigned Depth =
Op.getConstantOperandVal(0);
18796 bool isPPC64 = PtrVT == MVT::i64;
18802 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18804 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18810 FrameAddr, MachinePointerInfo());
18814#define GET_REGISTER_MATCHER
18815#include "PPCGenAsmMatcher.inc"
18819 bool IsPPC64 = Subtarget.isPPC64();
18831 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18837 Reg = Reg.id() - PPC::R0 + PPC::X0;
18844 if (Subtarget.is32BitELFABI())
18849 if (Subtarget.isAIXABI())
18863 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18879 case Intrinsic::ppc_atomicrmw_xchg_i128:
18880 case Intrinsic::ppc_atomicrmw_add_i128:
18881 case Intrinsic::ppc_atomicrmw_sub_i128:
18882 case Intrinsic::ppc_atomicrmw_nand_i128:
18883 case Intrinsic::ppc_atomicrmw_and_i128:
18884 case Intrinsic::ppc_atomicrmw_or_i128:
18885 case Intrinsic::ppc_atomicrmw_xor_i128:
18886 case Intrinsic::ppc_cmpxchg_i128:
18888 Info.memVT = MVT::i128;
18889 Info.ptrVal =
I.getArgOperand(0);
18891 Info.align =
Align(16);
18896 case Intrinsic::ppc_atomic_load_i128:
18898 Info.memVT = MVT::i128;
18899 Info.ptrVal =
I.getArgOperand(0);
18901 Info.align =
Align(16);
18905 case Intrinsic::ppc_atomic_store_i128:
18907 Info.memVT = MVT::i128;
18908 Info.ptrVal =
I.getArgOperand(2);
18910 Info.align =
Align(16);
18914 case Intrinsic::ppc_altivec_lvx:
18915 case Intrinsic::ppc_altivec_lvxl:
18916 case Intrinsic::ppc_altivec_lvebx:
18917 case Intrinsic::ppc_altivec_lvehx:
18918 case Intrinsic::ppc_altivec_lvewx:
18919 case Intrinsic::ppc_vsx_lxvd2x:
18920 case Intrinsic::ppc_vsx_lxvw4x:
18921 case Intrinsic::ppc_vsx_lxvd2x_be:
18922 case Intrinsic::ppc_vsx_lxvw4x_be:
18923 case Intrinsic::ppc_vsx_lxvl:
18924 case Intrinsic::ppc_vsx_lxvll: {
18927 case Intrinsic::ppc_altivec_lvebx:
18930 case Intrinsic::ppc_altivec_lvehx:
18933 case Intrinsic::ppc_altivec_lvewx:
18936 case Intrinsic::ppc_vsx_lxvd2x:
18937 case Intrinsic::ppc_vsx_lxvd2x_be:
18947 Info.ptrVal =
I.getArgOperand(0);
18950 Info.align =
Align(1);
18955 case Intrinsic::ppc_altivec_stvx:
18956 case Intrinsic::ppc_altivec_stvxl:
18957 case Intrinsic::ppc_altivec_stvebx:
18958 case Intrinsic::ppc_altivec_stvehx:
18959 case Intrinsic::ppc_altivec_stvewx:
18960 case Intrinsic::ppc_vsx_stxvd2x:
18961 case Intrinsic::ppc_vsx_stxvw4x:
18962 case Intrinsic::ppc_vsx_stxvd2x_be:
18963 case Intrinsic::ppc_vsx_stxvw4x_be:
18964 case Intrinsic::ppc_vsx_stxvl:
18965 case Intrinsic::ppc_vsx_stxvll: {
18968 case Intrinsic::ppc_altivec_stvebx:
18971 case Intrinsic::ppc_altivec_stvehx:
18974 case Intrinsic::ppc_altivec_stvewx:
18977 case Intrinsic::ppc_vsx_stxvd2x:
18978 case Intrinsic::ppc_vsx_stxvd2x_be:
18988 Info.ptrVal =
I.getArgOperand(1);
18991 Info.align =
Align(1);
18996 case Intrinsic::ppc_stdcx:
18997 case Intrinsic::ppc_stwcx:
18998 case Intrinsic::ppc_sthcx:
18999 case Intrinsic::ppc_stbcx: {
19001 auto Alignment =
Align(8);
19003 case Intrinsic::ppc_stdcx:
19006 case Intrinsic::ppc_stwcx:
19008 Alignment =
Align(4);
19010 case Intrinsic::ppc_sthcx:
19012 Alignment =
Align(2);
19014 case Intrinsic::ppc_stbcx:
19016 Alignment =
Align(1);
19021 Info.ptrVal =
I.getArgOperand(0);
19023 Info.align = Alignment;
19037 const AttributeList &FuncAttributes)
const {
19041 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19042 if (
Op.isMemset() && Subtarget.hasVSX()) {
19047 if (TailSize > 2 && TailSize <= 4) {
19052 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19057 if (Subtarget.isPPC64()) {
19068 assert(Ty->isIntegerTy());
19070 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19071 return !(BitSize == 0 || BitSize > 64);
19079 return NumBits1 == 64 && NumBits2 == 32;
19087 return NumBits1 == 64 && NumBits2 == 32;
19094 EVT MemVT = LD->getMemoryVT();
19095 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19096 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19112 "invalid fpext types");
19114 if (DestVT == MVT::f128)
19129 unsigned *
Fast)
const {
19143 !Subtarget.allowsUnalignedFPAccess())
19147 if (Subtarget.hasVSX()) {
19148 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19149 VT != MVT::v4f32 && VT != MVT::v4i32)
19156 if (VT == MVT::ppcf128)
19171 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19179 int64_t Imm = ConstNode->getSExtValue();
19200 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19202 switch (Ty->getScalarType()->getTypeID()) {
19207 return Subtarget.hasP9Vector();
19215 if (!
I->hasOneUse())
19219 assert(
User &&
"A single use instruction with no uses.");
19221 switch (
I->getOpcode()) {
19222 case Instruction::FMul: {
19224 if (
User->getOpcode() != Instruction::FSub &&
19225 User->getOpcode() != Instruction::FAdd)
19232 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19233 User->getFastMathFlags().allowContract();
19239 case Instruction::Load: {
19252 if (
User->getOpcode() != Instruction::Store)
19272 static const MCPhysReg ScratchRegs[] = {
19273 PPC::X12, PPC::LR8, PPC::CTR8, 0
19276 return ScratchRegs;
19280 const Constant *PersonalityFn)
const {
19281 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19285 const Constant *PersonalityFn)
const {
19286 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19291 EVT VT ,
unsigned DefinedValues)
const {
19292 if (VT == MVT::v2i64)
19293 return Subtarget.hasDirectMove();
19295 if (Subtarget.hasVSX())
19322 return PPCISD::FNMSUB;
19323 case PPCISD::FNMSUB:
19329 bool LegalOps,
bool OptForSize,
19331 unsigned Depth)
const {
19335 unsigned Opc =
Op.getOpcode();
19336 EVT VT =
Op.getValueType();
19340 case PPCISD::FNMSUB:
19360 if (Flags.hasNoSignedZeros()) {
19364 N0Cost,
Depth + 1);
19368 N1Cost,
Depth + 1);
19370 if (NegN0 && N0Cost <= N1Cost) {
19371 Cost = std::min(N0Cost, N2Cost);
19373 }
else if (NegN1) {
19374 Cost = std::min(N1Cost, N2Cost);
19394 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19400 bool ForCodeSize)
const {
19401 if (!VT.
isSimple() || !Subtarget.hasVSX())
19411 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19416 APSInt IntResult(16,
false);
19421 if (IsExact && IntResult <= 15 && IntResult >= -16)
19423 return Imm.isZero();
19426 return Imm.isPosZero();
19438 unsigned Opcode =
N->getOpcode();
19458 if (Mask->getZExtValue() == OpSizeInBits - 1)
19465 DAGCombinerInfo &DCI)
const {
19466 EVT VT =
N->getValueType(0);
19469 unsigned Opc =
N->getOpcode();
19471 "Unexpected opcode.");
19478 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19482 uint64_t SplatBits = 0;
19483 bool AddSplatCase =
false;
19487 AddSplatCase =
true;
19491 if (!AddSplatCase) {
19495 unsigned SplatBitSize;
19497 APInt APSplatBits, APSplatUndef;
19499 bool BVNIsConstantSplat =
19501 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19502 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19513 if (SplatBits == (EltBits - 1)) {
19517 NewOpc = PPCISD::SHL;
19520 NewOpc = PPCISD::SRL;
19523 NewOpc = PPCISD::SRA;
19527 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19535 if (EltTy != MVT::i64 || SplatBits != 1)
19538 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19541SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19545 if (
N->getValueType(0).isVector())
19546 return combineVectorShift(
N, DCI);
19550 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19553 N->getValueType(0) != MVT::i64)
19568 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19574SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19578 if (
N->getValueType(0).isVector())
19579 return combineVectorShift(
N, DCI);
19584SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19588 if (
N->getValueType(0).isVector())
19589 return combineVectorShift(
N, DCI);
19600 if (!Subtarget.isPPC64())
19606 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19608 Op.getValueType() != MVT::i64)
19612 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19613 Cmp.getOperand(0).getValueType() != MVT::i64)
19617 int64_t NegConstant = 0 -
Constant->getSExtValue();
19626 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19627 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19630 if (LHSHasPattern && !RHSHasPattern)
19632 else if (!LHSHasPattern && !RHSHasPattern)
19636 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19639 SDValue Z = Cmp.getOperand(0);
19641 int64_t NegConstant = 0 -
Constant->getSExtValue();
19654 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19672 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19702 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19705 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19713 if (!GSDN || !ConstNode)
19741 EVT VT =
N->getValueType(0);
19742 if (!Subtarget.hasVSX())
19746 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19758 unsigned NumOfEles =
RHS.getNumOperands();
19759 for (
unsigned i = 0; i < NumOfEles; ++i) {
19761 if (!CN || CN->getSExtValue() != 1)
19776SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19798 DAGCombinerInfo &DCI)
const {
19800 if (Subtarget.useCRBits()) {
19802 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19803 return CRTruncValue;
19810 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19813 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19823 EltToExtract = EltToExtract ? 0 : 1;
19833 return DCI.DAG.getNode(
19835 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19840SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19841 SelectionDAG &DAG = DCI.DAG;
19844 if (!ConstOpOrElement)
19852 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19853 switch (this->Subtarget.getCPUDirective()) {
19876 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19880 EVT VT =
N->getValueType(0);
19885 APInt MulAmtAbs = MulAmt.
abs();
19887 if ((MulAmtAbs - 1).isPowerOf2()) {
19891 if (!IsProfitable(IsNeg,
true, VT))
19904 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19908 if (!IsProfitable(IsNeg,
false, VT))
19929 DAGCombinerInfo &DCI)
const {
19933 SDNodeFlags
Flags =
N->getFlags();
19934 EVT VT =
N->getValueType(0);
19935 SelectionDAG &DAG = DCI.DAG;
19936 unsigned Opc =
N->getOpcode();
19938 bool LegalOps = !DCI.isBeforeLegalizeOps();
19946 if (!
Flags.hasNoSignedZeros())
19962bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19964 if (!Subtarget.is64BitELFABI())
19974 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19979 if (!Callee ||
Callee->isVarArg())
19992bool PPCTargetLowering::
19993isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19998 if (CI->getBitWidth() > 64)
20000 int64_t ConstVal = CI->getZExtValue();
20002 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20011PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20017 if ((Flags & FlagSet) == FlagSet)
20020 if ((Flags & FlagSet) == FlagSet)
20023 if ((Flags & FlagSet) == FlagSet)
20026 if ((Flags & FlagSet) == FlagSet)
20047 if ((FrameIndexAlign % 4) != 0)
20048 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20049 if ((FrameIndexAlign % 16) != 0)
20050 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20054 if ((FrameIndexAlign % 4) == 0)
20056 if ((FrameIndexAlign % 16) == 0)
20069 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20070 if ((Imm & 0x3) == 0)
20072 if ((Imm & 0xf) == 0)
20078 const APInt &ConstImm = CN->getAPIntValue();
20097 const APInt &ConstImm = CN->getAPIntValue();
20107 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20118 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20127unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20132 if (!Subtarget.hasP9Vector())
20137 if (Subtarget.hasPrefixInstrs())
20140 if (Subtarget.hasSPE())
20149 unsigned ParentOp = Parent->
getOpcode();
20153 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20154 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20166 if (LSB->isIndexed())
20172 assert(MN &&
"Parent should be a MemSDNode!");
20177 "Not expecting scalar integers larger than 16 bytes!");
20180 else if (
Size == 32)
20187 else if (
Size == 256) {
20188 assert(Subtarget.pairedVectorMemops() &&
20189 "256-bit vectors are only available when paired vector memops is "
20197 else if (MemVT == MVT::f128 || MemVT.
isVector())
20228 FlagSet &= ~PPC::MOF_NoExt;
20233 bool IsNonP1034BitConst =
20237 IsNonP1034BitConst)
20250 int16_t ForceXFormImm = 0;
20253 Disp =
N.getOperand(0);
20254 Base =
N.getOperand(1);
20265 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20266 Disp =
N.getOperand(0);
20267 Base =
N.getOperand(1);
20272 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20281 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20287 if (PartVT == MVT::f64 &&
20288 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20297SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20301 EVT RetVT =
Op.getValueType();
20308 EVT ArgVT =
N.getValueType();
20312 Entry.IsZExt = !Entry.IsSExt;
20313 Args.push_back(Entry);
20321 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20334SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20335 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20337 if (
Op.getValueType() == MVT::f32)
20338 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20340 if (
Op.getValueType() == MVT::f64)
20341 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20346bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20347 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20348 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20352bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20353 return Op.getNode()->getFlags().hasApproximateFuncs();
20356bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20360SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20361 const char *LibCallFloatName,
20362 const char *LibCallDoubleNameFinite,
20363 const char *LibCallFloatNameFinite,
20366 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20369 if (!isLowringToMASSFiniteSafe(
Op))
20370 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20373 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20374 LibCallDoubleNameFinite,
Op, DAG);
20378 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20379 "__xl_powf_finite",
Op, DAG);
20383 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20384 "__xl_sinf_finite",
Op, DAG);
20388 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20389 "__xl_cosf_finite",
Op, DAG);
20393 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20394 "__xl_logf_finite",
Op, DAG);
20398 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20399 "__xl_log10f_finite",
Op, DAG);
20403 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20404 "__xl_expf_finite",
Op, DAG);
20429 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20440 assert(Subtarget.isUsingPCRelativeCalls() &&
20441 "Must be using PC-Relative calls when a valid PC-Relative node is "
20471 Disp =
N.getOperand(1).getOperand(0);
20476 Base =
N.getOperand(0);
20484 EVT CNType = CN->getValueType(0);
20485 uint64_t CNImm = CN->getZExtValue();
20496 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20498 int32_t Addr = (int32_t)CNImm;
20503 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20519 unsigned Opcode =
N.getOpcode();
20527 Base =
N.getOperand(0);
20546 Base = FI ?
N :
N.getOperand(1);
20547 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20558 bool IsVarArg)
const {
20568 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20605 return Intrinsic::ppc_atomicrmw_xchg_i128;
20607 return Intrinsic::ppc_atomicrmw_add_i128;
20609 return Intrinsic::ppc_atomicrmw_sub_i128;
20611 return Intrinsic::ppc_atomicrmw_and_i128;
20613 return Intrinsic::ppc_atomicrmw_or_i128;
20615 return Intrinsic::ppc_atomicrmw_xor_i128;
20617 return Intrinsic::ppc_atomicrmw_nand_i128;
20625 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20629 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20631 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20632 Value *LoHi = Builder.CreateIntrinsic(
20634 {AlignedAddr, IncrLo, IncrHi});
20635 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20636 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20637 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20638 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20639 return Builder.CreateOr(
20640 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20647 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20653 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20655 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20656 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20658 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20661 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20663 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20664 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20665 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20666 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20667 return Builder.CreateOr(
20668 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20672 return Subtarget.useCRBits();
20677bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
20688 DAGCombinerInfo &DCI)
const {
20693 EVT ResVT =
N->getValueType(0);
20695 EVT SrcVT = Src.getValueType();
20700 if (ResVT != MVT::i16 && ResVT != MVT::i8)
20703 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
20716 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
20717 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
20718 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
20720 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
20728 SmallVector<int, 16> BitIndices(16, 128);
20732 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
20733 if (IsV8i8 && IsLE)
20734 BitIndices[Idx] += 64;
20737 std::reverse(BitIndices.begin(), BitIndices.end());
20739 for (
auto Idx : BitIndices)
20744 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS)
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue 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 void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left, SelectionDAG &DAG)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static 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 Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static 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 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...
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble()
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
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.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & 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.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI 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
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...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
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...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
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
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...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
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...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
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...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
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 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.
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 PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ 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.
@ 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...
@ 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...
@ 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
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr 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 raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ 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...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.