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()) {
1460 if (Subtarget.useCRBits()) {
1476 auto CPUDirective = Subtarget.getCPUDirective();
1477 switch (CPUDirective) {
1500 if (Subtarget.enableMachineScheduler())
1574void PPCTargetLowering::initializeAddrModeMap() {
1625 if (MaxAlign == MaxMaxAlign)
1628 if (MaxMaxAlign >= 32 &&
1629 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1630 MaxAlign =
Align(32);
1631 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1633 MaxAlign =
Align(16);
1637 if (EltAlign > MaxAlign)
1638 MaxAlign = EltAlign;
1640 for (
auto *EltTy : STy->elements()) {
1643 if (EltAlign > MaxAlign)
1644 MaxAlign = EltAlign;
1645 if (MaxAlign == MaxMaxAlign)
1658 if (Subtarget.hasAltivec())
1664 return Subtarget.useSoftFloat();
1668 return Subtarget.hasSPE();
1676 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1677 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1681 if (VTy->getScalarType()->isIntegerTy()) {
1683 if (ElemSizeInBits == 32) {
1684 Index = Subtarget.isLittleEndian() ? 2 : 1;
1687 if (ElemSizeInBits == 64) {
1688 Index = Subtarget.isLittleEndian() ? 1 : 0;
1699 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1716 return CFP->getValueAPF().isZero();
1721 return CFP->getValueAPF().isZero();
1729 return Op < 0 ||
Op == Val;
1741 if (ShuffleKind == 0) {
1744 for (
unsigned i = 0; i != 16; ++i)
1747 }
else if (ShuffleKind == 2) {
1750 for (
unsigned i = 0; i != 16; ++i)
1753 }
else if (ShuffleKind == 1) {
1754 unsigned j = IsLE ? 0 : 1;
1755 for (
unsigned i = 0; i != 8; ++i)
1772 if (ShuffleKind == 0) {
1775 for (
unsigned i = 0; i != 16; i += 2)
1779 }
else if (ShuffleKind == 2) {
1782 for (
unsigned i = 0; i != 16; i += 2)
1786 }
else if (ShuffleKind == 1) {
1787 unsigned j = IsLE ? 0 : 2;
1788 for (
unsigned i = 0; i != 8; i += 2)
1809 if (!Subtarget.hasP8Vector())
1813 if (ShuffleKind == 0) {
1816 for (
unsigned i = 0; i != 16; i += 4)
1822 }
else if (ShuffleKind == 2) {
1825 for (
unsigned i = 0; i != 16; i += 4)
1831 }
else if (ShuffleKind == 1) {
1832 unsigned j = IsLE ? 0 : 4;
1833 for (
unsigned i = 0; i != 8; i += 4)
1850 unsigned LHSStart,
unsigned RHSStart) {
1851 if (
N->getValueType(0) != MVT::v16i8)
1853 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1854 "Unsupported merge size!");
1856 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1857 for (
unsigned j = 0; j != UnitSize; ++j) {
1859 LHSStart+j+i*UnitSize) ||
1861 RHSStart+j+i*UnitSize))
1876 if (ShuffleKind == 1)
1878 else if (ShuffleKind == 2)
1883 if (ShuffleKind == 1)
1885 else if (ShuffleKind == 0)
1901 if (ShuffleKind == 1)
1903 else if (ShuffleKind == 2)
1908 if (ShuffleKind == 1)
1910 else if (ShuffleKind == 0)
1960 unsigned RHSStartValue) {
1961 if (
N->getValueType(0) != MVT::v16i8)
1964 for (
unsigned i = 0; i < 2; ++i)
1965 for (
unsigned j = 0; j < 4; ++j)
1967 i*RHSStartValue+j+IndexOffset) ||
1969 i*RHSStartValue+j+IndexOffset+8))
1991 unsigned indexOffset = CheckEven ? 4 : 0;
1992 if (ShuffleKind == 1)
1994 else if (ShuffleKind == 2)
2000 unsigned indexOffset = CheckEven ? 0 : 4;
2001 if (ShuffleKind == 1)
2003 else if (ShuffleKind == 0)
2019 if (
N->getValueType(0) != MVT::v16i8)
2026 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2029 if (i == 16)
return -1;
2034 if (ShiftAmt < i)
return -1;
2039 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2041 for (++i; i != 16; ++i)
2044 }
else if (ShuffleKind == 1) {
2046 for (++i; i != 16; ++i)
2053 ShiftAmt = 16 - ShiftAmt;
2062 EVT VT =
N->getValueType(0);
2063 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2064 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2067 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2071 if (
N->getMaskElt(0) % EltSize != 0)
2076 unsigned ElementBase =
N->getMaskElt(0);
2079 if (ElementBase >= 16)
2084 for (
unsigned i = 1; i != EltSize; ++i)
2085 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2088 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2090 if (
N->getMaskElt(i) < 0) {
2091 for (
unsigned j = 1; j != EltSize; ++j)
2092 if (
N->getMaskElt(i + j) >= 0)
2095 for (
unsigned j = 0; j != EltSize; ++j)
2096 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2113 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2114 "Unexpected element width.");
2115 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2117 unsigned NumOfElem = 16 / Width;
2118 unsigned MaskVal[16];
2119 for (
unsigned i = 0; i < NumOfElem; ++i) {
2120 MaskVal[0] =
N->getMaskElt(i * Width);
2121 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2123 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2127 for (
unsigned int j = 1; j < Width; ++j) {
2128 MaskVal[j] =
N->getMaskElt(i * Width + j);
2129 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2139 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2144 unsigned M0 =
N->getMaskElt(0) / 4;
2145 unsigned M1 =
N->getMaskElt(4) / 4;
2146 unsigned M2 =
N->getMaskElt(8) / 4;
2147 unsigned M3 =
N->getMaskElt(12) / 4;
2148 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2149 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2154 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2155 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2156 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2157 InsertAtByte = IsLE ? 12 : 0;
2162 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2163 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2164 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2165 InsertAtByte = IsLE ? 8 : 4;
2170 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2171 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2172 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2173 InsertAtByte = IsLE ? 4 : 8;
2178 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2179 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2180 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2181 InsertAtByte = IsLE ? 0 : 12;
2188 if (
N->getOperand(1).isUndef()) {
2191 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2192 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2193 InsertAtByte = IsLE ? 12 : 0;
2196 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2197 InsertAtByte = IsLE ? 8 : 4;
2200 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2201 InsertAtByte = IsLE ? 4 : 8;
2204 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2205 InsertAtByte = IsLE ? 0 : 12;
2214 bool &Swap,
bool IsLE) {
2215 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2221 unsigned M0 =
N->getMaskElt(0) / 4;
2222 unsigned M1 =
N->getMaskElt(4) / 4;
2223 unsigned M2 =
N->getMaskElt(8) / 4;
2224 unsigned M3 =
N->getMaskElt(12) / 4;
2228 if (
N->getOperand(1).isUndef()) {
2229 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2230 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2233 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2239 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2243 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2248 ShiftElts = (8 -
M0) % 8;
2249 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2254 ShiftElts = (4 -
M0) % 4;
2259 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2264 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2276 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2281 for (
int i = 0; i < 16; i += Width)
2282 if (
N->getMaskElt(i) != i + Width - 1)
2313 bool &Swap,
bool IsLE) {
2314 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2320 unsigned M0 =
N->getMaskElt(0) / 8;
2321 unsigned M1 =
N->getMaskElt(8) / 8;
2322 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2326 if (
N->getOperand(1).isUndef()) {
2327 if ((
M0 |
M1) < 2) {
2328 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2336 if (
M0 > 1 &&
M1 < 2) {
2346 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2351 }
else if (
M0 > 1 &&
M1 < 2) {
2359 DM = (
M0 << 1) + (
M1 & 1);
2374 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2379 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2395 unsigned EltSize = 16/
N->getNumOperands();
2396 if (EltSize < ByteSize) {
2397 unsigned Multiple = ByteSize/EltSize;
2399 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2402 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2403 if (
N->getOperand(i).isUndef())
continue;
2407 if (!UniquedVals[i&(Multiple-1)].
getNode())
2408 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2409 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2419 bool LeadingZero =
true;
2420 bool LeadingOnes =
true;
2421 for (
unsigned i = 0; i != Multiple-1; ++i) {
2422 if (!UniquedVals[i].
getNode())
continue;
2429 if (!UniquedVals[Multiple-1].
getNode())
2436 if (!UniquedVals[Multiple-1].
getNode())
2447 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2448 if (
N->getOperand(i).isUndef())
continue;
2450 OpVal =
N->getOperand(i);
2451 else if (OpVal !=
N->getOperand(i))
2457 unsigned ValSizeInBytes = EltSize;
2460 Value = CN->getZExtValue();
2462 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2469 if (ValSizeInBytes < ByteSize)
return SDValue();
2480 if (MaskVal == 0)
return SDValue();
2500 Imm = (int16_t)
N->getAsZExtVal();
2501 if (
N->getValueType(0) == MVT::i32)
2502 return Imm == (int32_t)
N->getAsZExtVal();
2504 return Imm == (int64_t)
N->getAsZExtVal();
2522 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2530 for (
SDNode *U :
N->users()) {
2532 if (Memop->getMemoryVT() == MVT::f64) {
2533 Base =
N.getOperand(0);
2534 Index =
N.getOperand(1);
2577 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2579 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2582 Base =
N.getOperand(0);
2583 Index =
N.getOperand(1);
2585 }
else if (
N.getOpcode() ==
ISD::OR) {
2587 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2599 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2600 Base =
N.getOperand(0);
2601 Index =
N.getOperand(1);
2671 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2677 Base =
N.getOperand(0);
2680 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2682 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2683 "Cannot handle constant offsets yet!");
2684 Disp =
N.getOperand(1).getOperand(0);
2689 Base =
N.getOperand(0);
2692 }
else if (
N.getOpcode() ==
ISD::OR) {
2695 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2709 Base =
N.getOperand(0);
2722 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2725 CN->getValueType(0));
2730 if ((CN->getValueType(0) == MVT::i32 ||
2731 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2732 (!EncodingAlignment ||
2733 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2734 int Addr = (int)CN->getZExtValue();
2741 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2762 if (
N.getValueType() != MVT::i64)
2775 Base =
N.getOperand(0);
2791 Base =
N.getOperand(0);
2824 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2825 Base =
N.getOperand(0);
2826 Index =
N.getOperand(1);
2848 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2869 EVT MemVT = LD->getMemoryVT();
2876 if (!ST.hasP8Vector())
2881 if (!ST.hasP9Vector())
2893 if (
Use.getResNo() == 0 &&
2895 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2915 Ptr = LD->getBasePtr();
2916 VT = LD->getMemoryVT();
2917 Alignment = LD->getAlign();
2919 Ptr = ST->getBasePtr();
2920 VT = ST->getMemoryVT();
2921 Alignment = ST->getAlign();
2960 if (VT != MVT::i64) {
2965 if (Alignment <
Align(4))
2975 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
2992 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3034 EVT VT = Subtarget.getScalarIntVT();
3036 : Subtarget.isAIXABI()
3041 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3048 EVT PtrVT =
Op.getValueType();
3054 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3055 if (Subtarget.isUsingPCRelativeCalls()) {
3060 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3064 return getTOCEntry(DAG, SDLoc(CP), GA);
3067 unsigned MOHiFlag, MOLoFlag;
3071 if (IsPIC && Subtarget.isSVR4ABI()) {
3074 return getTOCEntry(DAG, SDLoc(CP), GA);
3097 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3104 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3121 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3134 EVT PtrVT =
Op.getValueType();
3152 return getTOCEntry(DAG,
SDLoc(JT), GA);
3155 unsigned MOHiFlag, MOLoFlag;
3159 if (IsPIC && Subtarget.isSVR4ABI()) {
3162 return getTOCEntry(DAG, SDLoc(GA), GA);
3172 EVT PtrVT =
Op.getValueType();
3177 if (Subtarget.isUsingPCRelativeCalls()) {
3188 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3191 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3200 unsigned MOHiFlag, MOLoFlag;
3210 if (Subtarget.isAIXABI())
3211 return LowerGlobalTLSAddressAIX(
Op, DAG);
3213 return LowerGlobalTLSAddressLinux(
Op, DAG);
3235 if (
I.getOpcode() == Instruction::Call)
3237 if (
Function *CF = CI->getCalledFunction())
3238 if (CF->isDeclaration() &&
3239 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3247 unsigned TLSGVCnt = TLSGV.
size();
3257 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3270 const GlobalValue *GV = GA->
getGlobal();
3272 bool Is64Bit = Subtarget.isPPC64();
3276 if (Subtarget.hasAIXShLibTLSModelOpt())
3286 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3287 bool HasAIXSmallTLSGlobalAttr =
false;
3290 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3294 if (GVar->hasAttribute(
"aix-small-tls"))
3295 HasAIXSmallTLSGlobalAttr =
true;
3314 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3315 IsTLSLocalExecModel) {
3320 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3330 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3335 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3337 "currently only supported on AIX (64-bit mode).");
3339 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3343 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3347 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3349 "currently only supported on AIX (64-bit mode).");
3357 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3360 GlobalVariable *TLSGV =
3364 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3367 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3369 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3378 if (HasAIXSmallLocalDynamicTLS) {
3383 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3387 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3400 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3401 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3402 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3417 const GlobalValue *GV = GA->
getGlobal();
3419 bool is64bit = Subtarget.isPPC64();
3427 if (Subtarget.isUsingPCRelativeCalls()) {
3432 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3433 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3444 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3448 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3455 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3457 MachinePointerInfo());
3464 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3466 if (!TM.isPositionIndependent())
3467 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3473 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3475 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3479 if (Subtarget.isUsingPCRelativeCalls()) {
3482 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3490 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3498 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3503 if (Subtarget.isUsingPCRelativeCalls()) {
3507 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3508 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3516 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3525 PtrVT, GOTPtr, TGA, TGA);
3527 PtrVT, TLSAddr, TGA);
3528 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3536 EVT PtrVT =
Op.getValueType();
3539 const GlobalValue *GV = GSDN->
getGlobal();
3543 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3544 if (Subtarget.isUsingPCRelativeCalls()) {
3551 MachinePointerInfo());
3556 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3561 return getTOCEntry(DAG,
DL, GA);
3564 unsigned MOHiFlag, MOLoFlag;
3568 if (IsPIC && Subtarget.isSVR4ABI()) {
3572 return getTOCEntry(DAG,
DL, GA);
3584 bool IsStrict =
Op->isStrictFPOpcode();
3590 EVT LHSVT =
LHS.getValueType();
3594 if (LHSVT == MVT::f128) {
3595 assert(!Subtarget.hasP9Vector() &&
3596 "SETCC for f128 is already legal under Power9!");
3607 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3609 if (
Op.getValueType() == MVT::v2i64) {
3612 if (
LHS.getValueType() == MVT::v2i64) {
3620 int ShuffV[] = {1, 0, 3, 2};
3625 dl, MVT::v4i32, Shuff, SetCC32));
3642 if (
C->isAllOnes() ||
C->isZero())
3652 EVT VT =
Op.getValueType();
3660 SDNode *
Node =
Op.getNode();
3661 EVT VT =
Node->getValueType(0);
3668 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3672 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3675 if (VT == MVT::i64) {
3694 FprPtr, MachinePointerInfo(SV), MVT::i8);
3705 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3706 InChain = OverflowArea.
getValue(1);
3709 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3739 MachinePointerInfo(SV), MVT::i8);
3752 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3753 MachinePointerInfo(), MVT::i32);
3755 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3759 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3765 false,
true,
nullptr, std::nullopt,
3766 MachinePointerInfo(), MachinePointerInfo());
3771 return Op.getOperand(0);
3776 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3780 "Expecting Inline ASM node.");
3790 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3795 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3796 unsigned NumVals =
Flags.getNumOperandRegisters();
3799 switch (
Flags.getKind()) {
3810 for (; NumVals; --NumVals, ++i) {
3812 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3835 if (Subtarget.isAIXABI()) {
3839 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3840 MaybeAlign PointerAlign(PointerSize);
3841 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3844 : MachineMemOperand::MONone;
3851 const Value *TrampolineAddr =
3861 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3862 PointerAlign, MMOFlags);
3864 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3865 MachinePointerInfo(TrampolineAddr, 0));
3869 SDValue TOCFromDescriptorPtr =
3871 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3872 MachinePointerInfo(Func, TOCPointerOffset),
3873 PointerAlign, MMOFlags);
3874 SDValue TrampolineTOCPointer =
3878 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3879 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3885 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3886 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3893 bool isPPC64 = (PtrVT == MVT::i64);
3897 Args.emplace_back(Trmp, IntPtrTy);
3900 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3902 Args.emplace_back(FPtr, IntPtrTy);
3903 Args.emplace_back(Nest, IntPtrTy);
3906 TargetLowering::CallLoweringInfo CLI(DAG);
3907 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3911 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3912 return CallResult.second;
3917 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3922 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3927 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3928 MachinePointerInfo(SV));
3962 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3965 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3968 uint64_t FPROffset = 1;
3976 MachinePointerInfo(SV), MVT::i8);
3977 uint64_t nextOffset = FPROffset;
3984 MachinePointerInfo(SV, nextOffset), MVT::i8);
3985 nextOffset += StackOffset;
3986 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3989 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3990 MachinePointerInfo(SV, nextOffset));
3991 nextOffset += FrameOffset;
3992 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3995 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3996 MachinePointerInfo(SV, nextOffset));
4001static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4002 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4003 PPC::F11, PPC::F12, PPC::F13};
4008 unsigned PtrByteSize) {
4010 if (Flags.isByVal())
4011 ArgSize = Flags.getByValSize();
4015 if (!Flags.isInConsecutiveRegs())
4016 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4025 unsigned PtrByteSize) {
4026 Align Alignment(PtrByteSize);
4029 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4030 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4031 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4032 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4033 Alignment =
Align(16);
4036 if (Flags.isByVal()) {
4037 auto BVAlign = Flags.getNonZeroByValAlign();
4038 if (BVAlign > PtrByteSize) {
4039 if (BVAlign.value() % PtrByteSize != 0)
4041 "ByVal alignment is not a multiple of the pointer size");
4043 Alignment = BVAlign;
4048 if (Flags.isInConsecutiveRegs()) {
4052 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4066 unsigned PtrByteSize,
unsigned LinkageSize,
4067 unsigned ParamAreaSize,
unsigned &ArgOffset,
4068 unsigned &AvailableFPRs,
4069 unsigned &AvailableVRs) {
4070 bool UseMemory =
false;
4075 ArgOffset =
alignTo(ArgOffset, Alignment);
4078 if (ArgOffset >= LinkageSize + ParamAreaSize)
4083 if (Flags.isInConsecutiveRegsLast())
4084 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4087 if (ArgOffset > LinkageSize + ParamAreaSize)
4092 if (!Flags.isByVal()) {
4093 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4094 if (AvailableFPRs > 0) {
4098 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4099 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4100 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4101 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4102 if (AvailableVRs > 0) {
4114 unsigned NumBytes) {
4118SDValue PPCTargetLowering::LowerFormalArguments(
4122 if (Subtarget.isAIXABI())
4123 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4125 if (Subtarget.is64BitELFABI())
4126 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4128 assert(Subtarget.is32BitELFABI());
4129 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4133SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4169 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4175 const Align PtrAlign(4);
4183 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4184 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4187 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4188 CCValAssign &VA = ArgLocs[i];
4192 const TargetRegisterClass *RC;
4200 RC = &PPC::GPRCRegClass;
4203 if (Subtarget.hasP8Vector())
4204 RC = &PPC::VSSRCRegClass;
4205 else if (Subtarget.hasSPE())
4206 RC = &PPC::GPRCRegClass;
4208 RC = &PPC::F4RCRegClass;
4211 if (Subtarget.hasVSX())
4212 RC = &PPC::VSFRCRegClass;
4213 else if (Subtarget.hasSPE())
4215 RC = &PPC::GPRCRegClass;
4217 RC = &PPC::F8RCRegClass;
4222 RC = &PPC::VRRCRegClass;
4225 RC = &PPC::VRRCRegClass;
4229 RC = &PPC::VRRCRegClass;
4236 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4237 assert(i + 1 < e &&
"No second half of double precision argument");
4242 if (!Subtarget.isLittleEndian())
4244 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4249 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4250 if (ValVT == MVT::i1)
4265 ArgOffset += ArgSize - ObjSize;
4283 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4288 unsigned MinReservedArea = CCByValInfo.getStackSize();
4289 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4305 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4306 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4308 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4311 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4314 unsigned NumFPArgRegs = std::size(FPArgRegs);
4323 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4324 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4327 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4340 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4355 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4359 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4372 if (!MemOps.
empty())
4383 const SDLoc &dl)
const {
4387 else if (
Flags.isZExt())
4394SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4400 bool isELFv2ABI = Subtarget.isELFv2ABI();
4401 bool isLittleEndian = Subtarget.isLittleEndian();
4404 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4407 "fastcc not supported on varargs functions");
4413 unsigned PtrByteSize = 8;
4414 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4417 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4418 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4421 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4422 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4425 const unsigned Num_GPR_Regs = std::size(GPR);
4427 const unsigned Num_VR_Regs = std::size(VR);
4435 bool HasParameterArea = !isELFv2ABI || isVarArg;
4436 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4437 unsigned NumBytes = LinkageSize;
4438 unsigned AvailableFPRs = Num_FPR_Regs;
4439 unsigned AvailableVRs = Num_VR_Regs;
4440 for (
const ISD::InputArg &In : Ins) {
4441 if (
In.Flags.isNest())
4445 LinkageSize, ParamAreaSize, NumBytes,
4446 AvailableFPRs, AvailableVRs))
4447 HasParameterArea =
true;
4454 unsigned ArgOffset = LinkageSize;
4455 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4458 unsigned CurArgIdx = 0;
4459 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4461 bool needsLoad =
false;
4462 EVT ObjectVT = Ins[ArgNo].VT;
4463 EVT OrigVT = Ins[ArgNo].ArgVT;
4465 unsigned ArgSize = ObjSize;
4466 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4467 if (Ins[ArgNo].isOrigArg()) {
4468 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4469 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4474 unsigned CurArgOffset;
4476 auto ComputeArgOffset = [&]() {
4480 ArgOffset =
alignTo(ArgOffset, Alignment);
4481 CurArgOffset = ArgOffset;
4488 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4489 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4494 if (
Flags.isByVal()) {
4495 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4501 ObjSize =
Flags.getByValSize();
4502 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4524 if (HasParameterArea ||
4525 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4532 if (ObjSize < PtrByteSize) {
4536 if (!isLittleEndian) {
4542 if (GPR_idx != Num_GPR_Regs) {
4549 MachinePointerInfo(&*FuncArg), ObjType);
4554 ArgOffset += PtrByteSize;
4563 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4564 if (GPR_idx == Num_GPR_Regs)
4575 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4579 MachinePointerInfo(&*FuncArg, j), ObjType);
4583 ArgOffset += ArgSize;
4592 if (
Flags.isNest()) {
4597 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4598 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4606 if (GPR_idx != Num_GPR_Regs) {
4611 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4614 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4620 ArgSize = PtrByteSize;
4631 if (FPR_idx != Num_FPR_Regs) {
4634 if (ObjectVT == MVT::f32)
4636 Subtarget.hasP8Vector()
4637 ? &PPC::VSSRCRegClass
4638 : &PPC::F4RCRegClass);
4641 ? &PPC::VSFRCRegClass
4642 : &PPC::F8RCRegClass);
4657 if (ObjectVT == MVT::f32) {
4658 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4676 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4677 ArgOffset += ArgSize;
4678 if (
Flags.isInConsecutiveRegsLast())
4679 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4693 if (VR_idx != Num_VR_Regs) {
4710 if (ObjSize < ArgSize && !isLittleEndian)
4711 CurArgOffset += ArgSize - ObjSize;
4714 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4721 unsigned MinReservedArea;
4722 if (HasParameterArea)
4723 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4725 MinReservedArea = LinkageSize;
4742 int Depth = ArgOffset;
4751 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4752 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4764 if (!MemOps.
empty())
4773 unsigned ParamSize) {
4775 if (!isTailCall)
return 0;
4779 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4781 if (SPDiff < FI->getTailCallSPDelta())
4797 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4856 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4859 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4871 const unsigned PtrByteSize = 8;
4875 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4876 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4879 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4880 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4883 const unsigned NumGPRs = std::size(GPR);
4884 const unsigned NumFPRs = 13;
4885 const unsigned NumVRs = std::size(VR);
4886 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4888 unsigned NumBytes = LinkageSize;
4889 unsigned AvailableFPRs = NumFPRs;
4890 unsigned AvailableVRs = NumVRs;
4893 if (Param.Flags.isNest())
continue;
4896 LinkageSize, ParamAreaSize, NumBytes,
4897 AvailableFPRs, AvailableVRs))
4908 auto CalleeArgEnd = CB.
arg_end();
4911 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4912 const Value* CalleeArg = *CalleeArgIter;
4913 const Value* CallerArg = &(*CallerArgIter);
4914 if (CalleeArg == CallerArg)
4940 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4950bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4955 bool isCalleeExternalSymbol)
const {
4958 if (
DisableSCO && !TailCallOpt)
return false;
4961 if (isVarArg)
return false;
4968 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5004 if (!Subtarget.isUsingPCRelativeCalls() &&
5009 if (!Subtarget.isUsingPCRelativeCalls() &&
5037bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5050 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5071 if (!
C)
return nullptr;
5073 int Addr =
C->getZExtValue();
5074 if ((Addr & 3) != 0 ||
5080 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5087struct TailCallArgumentInfo {
5092 TailCallArgumentInfo() =
default;
5102 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5103 SDValue Arg = TailCallArgs[i].Arg;
5104 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5105 int FI = TailCallArgs[i].FrameIdx;
5108 Chain, dl, Arg, FIN,
5117 int SPDiff,
const SDLoc &dl) {
5123 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5124 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5126 NewRetAddrLoc,
true);
5129 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5139 int SPDiff,
unsigned ArgOffset,
5141 int Offset = ArgOffset + SPDiff;
5144 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5146 TailCallArgumentInfo Info;
5148 Info.FrameIdxOp = FIN;
5156SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5161 LROpOut = getReturnAddrFrameIndex(DAG);
5162 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5163 MachinePointerInfo());
5180 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5188 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5212 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5222 if (!MemOpChains2.
empty())
5246SDValue PPCTargetLowering::LowerCallResult(
5254 CCRetInfo.AnalyzeCallResult(
5260 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5261 CCValAssign &VA = RVLocs[i];
5266 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5276 if (!Subtarget.isLittleEndian())
5278 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5344 bool IsStrictFPCall =
false) {
5346 return PPCISD::TC_RETURN;
5348 unsigned RetOpc = 0;
5363 RetOpc = PPCISD::CALL_NOTOC;
5378 RetOpc = PPCISD::CALL;
5379 if (IsStrictFPCall) {
5383 case PPCISD::BCTRL_LOAD_TOC:
5384 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5387 RetOpc = PPCISD::BCTRL_RM;
5389 case PPCISD::CALL_NOTOC:
5390 RetOpc = PPCISD::CALL_NOTOC_RM;
5393 RetOpc = PPCISD::CALL_RM;
5395 case PPCISD::CALL_NOP:
5396 RetOpc = PPCISD::CALL_NOP_RM;
5410 auto isLocalCallee = [&]() {
5426 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5442 return getAIXFuncEntryPointSymbolSDNode(GV);
5449 const char *SymName = S->getSymbol();
5456 return getAIXFuncEntryPointSymbolSDNode(
F);
5462 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5470 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5477 assert(Callee.getNode() &&
"What no callee?");
5483 "Expected a CALLSEQ_STARTSDNode.");
5500 SDValue MTCTROps[] = {Chain, Callee, Glue};
5501 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5502 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5542 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5561 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5562 Alignment, MMOFlags);
5569 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5576 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5588 "Nest parameter is not supported on AIX.");
5604 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5607 const bool IsPPC64 = Subtarget.isPPC64();
5612 Ops.push_back(Chain);
5616 Ops.push_back(Callee);
5636 Ops.push_back(AddTOC);
5647 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5656 for (
const auto &[
Reg,
N] : RegsToPass)
5674 assert(Mask &&
"Missing call preserved mask for calling convention");
5679 Ops.push_back(Glue);
5682SDValue PPCTargetLowering::FinishCall(
5689 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5690 Subtarget.isAIXABI())
5697 if (!CFlags.IsIndirect)
5699 else if (Subtarget.usesFunctionDescriptors())
5701 dl, CFlags.HasNest, Subtarget);
5711 if (CFlags.IsTailCall) {
5719 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5720 "Expecting a global address, external symbol, absolute value, "
5721 "register or an indirect tail call when PC Relative calls are "
5724 assert(CallOpc == PPCISD::TC_RETURN &&
5725 "Unexpected call opcode for a tail call.");
5732 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5733 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5745 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5748 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5768 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5769 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5773bool PPCTargetLowering::isEligibleForTCO(
5778 bool isCalleeExternalSymbol)
const {
5782 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5783 return IsEligibleForTailCallOptimization_64SVR4(
5784 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5785 isCalleeExternalSymbol);
5787 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5815 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5830 "Callee should be an llvm::Function object.");
5833 <<
"\nTCO callee: ");
5840 "site marked musttail");
5847 Callee = LowerGlobalAddress(Callee, DAG);
5850 CallConv, isTailCall, isVarArg, isPatchPoint,
5853 Subtarget.is64BitELFABI() &&
5857 if (Subtarget.isAIXABI())
5858 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5861 assert(Subtarget.isSVR4ABI());
5862 if (Subtarget.isPPC64())
5863 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5865 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5869SDValue PPCTargetLowering::LowerCall_32SVR4(
5880 const bool IsVarArg = CFlags.IsVarArg;
5881 const bool IsTailCall = CFlags.IsTailCall;
5887 const Align PtrAlign(4);
5898 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5906 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5909 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5916 unsigned NumArgs = Outs.
size();
5918 for (
unsigned i = 0; i != NumArgs; ++i) {
5919 MVT ArgVT = Outs[i].VT;
5920 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5925 Outs[i].OrigTy, CCInfo);
5928 ArgFlags, Outs[i].OrigTy, CCInfo);
5933 errs() <<
"Call operand #" << i <<
" has unhandled type "
5946 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
5949 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5956 unsigned NumBytes = CCByValInfo.getStackSize();
5970 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5981 bool seenFloatArg =
false;
5986 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5988 ++i, ++RealArgIdx) {
5989 CCValAssign &VA = ArgLocs[i];
5990 SDValue Arg = OutVals[RealArgIdx];
5991 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
5993 if (
Flags.isByVal()) {
5998 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5999 CCValAssign &ByValVA = ByValArgLocs[
j++];
6021 Chain = CallSeqStart = NewCallSeqStart;
6040 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6041 bool IsLE = Subtarget.isLittleEndian();
6042 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6045 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6047 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6062 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6071 if (!MemOpChains.
empty())
6077 for (
const auto &[
Reg,
N] : RegsToPass) {
6085 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6088 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6098 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6099 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6104SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6116 return NewCallSeqStart;
6119SDValue PPCTargetLowering::LowerCall_64SVR4(
6126 bool isELFv2ABI = Subtarget.isELFv2ABI();
6127 bool isLittleEndian = Subtarget.isLittleEndian();
6129 bool IsSibCall =
false;
6133 unsigned PtrByteSize = 8;
6146 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6148 assert(!(IsFastCall && CFlags.IsVarArg) &&
6149 "fastcc not supported on varargs functions");
6155 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6156 unsigned NumBytes = LinkageSize;
6157 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6160 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6161 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6164 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6165 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6168 const unsigned NumGPRs = std::size(GPR);
6170 const unsigned NumVRs = std::size(VR);
6176 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6177 if (!HasParameterArea) {
6178 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6179 unsigned AvailableFPRs = NumFPRs;
6180 unsigned AvailableVRs = NumVRs;
6181 unsigned NumBytesTmp = NumBytes;
6182 for (
unsigned i = 0; i !=
NumOps; ++i) {
6183 if (Outs[i].
Flags.isNest())
continue;
6185 PtrByteSize, LinkageSize, ParamAreaSize,
6186 NumBytesTmp, AvailableFPRs, AvailableVRs))
6187 HasParameterArea =
true;
6193 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6198 HasParameterArea =
false;
6201 for (
unsigned i = 0; i !=
NumOps; ++i) {
6202 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6203 EVT ArgVT = Outs[i].VT;
6204 EVT OrigVT = Outs[i].ArgVT;
6210 if (
Flags.isByVal()) {
6211 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6212 if (NumGPRsUsed > NumGPRs)
6213 HasParameterArea =
true;
6220 if (++NumGPRsUsed <= NumGPRs)
6230 if (++NumVRsUsed <= NumVRs)
6234 if (++NumVRsUsed <= NumVRs)
6239 if (++NumFPRsUsed <= NumFPRs)
6243 HasParameterArea =
true;
6250 NumBytes =
alignTo(NumBytes, Alignement);
6253 if (
Flags.isInConsecutiveRegsLast())
6254 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6257 unsigned NumBytesActuallyUsed = NumBytes;
6267 if (HasParameterArea)
6268 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6270 NumBytes = LinkageSize;
6285 if (CFlags.IsTailCall)
6297 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6308 unsigned ArgOffset = LinkageSize;
6314 for (
unsigned i = 0; i !=
NumOps; ++i) {
6316 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6317 EVT ArgVT = Outs[i].VT;
6318 EVT OrigVT = Outs[i].ArgVT;
6327 auto ComputePtrOff = [&]() {
6331 ArgOffset =
alignTo(ArgOffset, Alignment);
6342 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6343 GPR_idx = std::min(GPR_idx, NumGPRs);
6350 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6356 if (
Flags.isByVal()) {
6374 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6375 if (GPR_idx != NumGPRs) {
6377 MachinePointerInfo(), VT);
6379 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6381 ArgOffset += PtrByteSize;
6386 if (GPR_idx == NumGPRs &&
Size < 8) {
6388 if (!isLittleEndian) {
6393 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6396 ArgOffset += PtrByteSize;
6405 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6406 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6411 if (
Size < 8 && GPR_idx != NumGPRs) {
6421 if (!isLittleEndian) {
6425 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6431 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6433 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6436 ArgOffset += PtrByteSize;
6442 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6445 if (GPR_idx != NumGPRs) {
6446 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6449 MachinePointerInfo(), ObjType);
6452 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6453 ArgOffset += PtrByteSize;
6455 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6467 if (
Flags.isNest()) {
6469 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6476 if (GPR_idx != NumGPRs) {
6477 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6482 assert(HasParameterArea &&
6483 "Parameter area must exist to pass an argument in memory.");
6485 true, CFlags.IsTailCall,
false, MemOpChains,
6486 TailCallArguments, dl);
6488 ArgOffset += PtrByteSize;
6491 ArgOffset += PtrByteSize;
6504 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6505 bool NeededLoad =
false;
6508 if (FPR_idx != NumFPRs)
6509 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6512 if (!NeedGPROrStack)
6514 else if (GPR_idx != NumGPRs && !IsFastCall) {
6528 }
else if (!
Flags.isInConsecutiveRegs()) {
6534 }
else if (ArgOffset % PtrByteSize != 0) {
6538 if (!isLittleEndian)
6543 }
else if (
Flags.isInConsecutiveRegsLast()) {
6546 if (!isLittleEndian)
6556 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6564 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6569 assert(HasParameterArea &&
6570 "Parameter area must exist to pass an argument in memory.");
6572 true, CFlags.IsTailCall,
false, MemOpChains,
6573 TailCallArguments, dl);
6580 if (!IsFastCall || NeededLoad) {
6582 Flags.isInConsecutiveRegs()) ? 4 : 8;
6583 if (
Flags.isInConsecutiveRegsLast())
6584 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6604 if (CFlags.IsVarArg) {
6605 assert(HasParameterArea &&
6606 "Parameter area must exist if we have a varargs call.");
6610 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6612 if (VR_idx != NumVRs) {
6614 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6616 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6619 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6620 if (GPR_idx == NumGPRs)
6625 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6627 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6633 if (VR_idx != NumVRs) {
6634 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6639 assert(HasParameterArea &&
6640 "Parameter area must exist to pass an argument in memory.");
6642 true, CFlags.IsTailCall,
true, MemOpChains,
6643 TailCallArguments, dl);
6654 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6655 "mismatch in size of parameter area");
6656 (void)NumBytesActuallyUsed;
6658 if (!MemOpChains.
empty())
6664 if (CFlags.IsIndirect) {
6668 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6673 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6683 if (isELFv2ABI && !CFlags.IsPatchPoint)
6684 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6690 for (
const auto &[
Reg,
N] : RegsToPass) {
6695 if (CFlags.IsTailCall && !IsSibCall)
6699 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6700 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6707 "Required alignment greater than stack alignment.");
6727 return RequiredAlign <= 8;
6732 return RequiredAlign <= 4;
6740 State.getMachineFunction().getSubtarget());
6741 const bool IsPPC64 = Subtarget.isPPC64();
6742 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6743 const Align PtrAlign(PtrSize);
6744 const Align StackAlign(16);
6747 if (ValVT == MVT::f128)
6751 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6752 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6754 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6755 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6758 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6759 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6760 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6765 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6774 if (ByValAlign > StackAlign)
6776 "16 are not supported.");
6779 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6783 if (ByValSize == 0) {
6785 State.getStackSize(), RegVT, LocInfo));
6790 unsigned NextReg = State.getFirstUnallocated(GPRs);
6791 while (NextReg != GPRs.
size() &&
6796 State.AllocateStack(PtrSize, PtrAlign);
6797 assert(
Reg &&
"Alocating register unexpectedly failed.");
6799 NextReg = State.getFirstUnallocated(GPRs);
6802 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6803 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6823 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6827 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6846 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6852 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6854 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6855 if (State.isVarArg()) {
6887 const unsigned VecSize = 16;
6888 const Align VecAlign(VecSize);
6890 if (!State.isVarArg()) {
6893 if (
MCRegister VReg = State.AllocateReg(VR)) {
6900 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6905 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6908 while (NextRegIndex != GPRs.
size() &&
6912 State.AllocateStack(PtrSize, PtrAlign);
6913 assert(
Reg &&
"Allocating register unexpectedly failed.");
6915 NextRegIndex = State.getFirstUnallocated(GPRs);
6923 if (
MCRegister VReg = State.AllocateReg(VR)) {
6926 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6927 State.AllocateReg(GPRs);
6928 State.AllocateStack(VecSize, VecAlign);
6932 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6938 if (NextRegIndex == GPRs.
size()) {
6939 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6947 if (GPRs[NextRegIndex] == PPC::R9) {
6948 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6952 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
6953 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
6954 assert(FirstReg && SecondReg &&
6955 "Allocating R9 or R10 unexpectedly failed.");
6966 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6969 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6971 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
6986 assert((IsPPC64 || SVT != MVT::i64) &&
6987 "i64 should have been split for 32-bit codegen.");
6995 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6997 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6999 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7007 return &PPC::VRRCRegClass;
7020 else if (Flags.isZExt())
7032 "Reg must be a valid argument register!");
7033 return LASize + 4 * (
Reg - PPC::R3);
7038 "Reg must be a valid argument register!");
7039 return LASize + 8 * (
Reg - PPC::X3);
7085SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7092 "Unexpected calling convention!");
7100 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7102 const bool IsPPC64 = Subtarget.isPPC64();
7103 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7109 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7110 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7114 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7115 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7116 uint64_t SaveStackPos = CCInfo.getStackSize();
7118 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7122 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7123 CCValAssign &VA = ArgLocs[
I++];
7128 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7129 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7141 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7143 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7149 MachinePointerInfo(),
Align(PtrByteSize));
7155 unsigned StoreSize =
7157 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7160 auto HandleMemLoc = [&]() {
7163 assert((ValSize <= LocSize) &&
7164 "Object size is larger than size of MemLoc");
7167 if (LocSize > ValSize)
7168 CurArgOffset += LocSize - ValSize;
7170 const bool IsImmutable =
7176 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7210 assert(isVarArg &&
"Only use custom memloc for vararg.");
7213 const unsigned OriginalValNo = VA.
getValNo();
7214 (void)OriginalValNo;
7216 auto HandleCustomVecRegLoc = [&]() {
7217 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7218 "Missing custom RegLoc.");
7221 "Unexpected Val type for custom RegLoc.");
7223 "ValNo mismatch between custom MemLoc and RegLoc.");
7227 Subtarget.hasVSX()));
7234 HandleCustomVecRegLoc();
7235 HandleCustomVecRegLoc();
7239 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7241 "Only 2 custom RegLocs expected for 64-bit codegen.");
7242 HandleCustomVecRegLoc();
7243 HandleCustomVecRegLoc();
7287 const unsigned Size =
7299 if (
Flags.isByVal()) {
7303 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7305 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7313 const TargetRegisterClass *RegClass =
7314 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7316 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7329 CopyFrom.
getValue(1), dl, CopyFrom,
7339 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7342 "RegLocs should be for ByVal argument.");
7344 const CCValAssign RL = ArgLocs[
I++];
7349 if (
Offset != StackSize) {
7351 "Expected MemLoc for remaining bytes.");
7352 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7366 Subtarget.hasVSX()));
7383 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7385 unsigned CallerReservedArea = std::max<unsigned>(
7386 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7392 CallerReservedArea =
7397 int VAListIndex = 0;
7401 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7402 unsigned FixedStackSize =
7403 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7419 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7420 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7422 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7423 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7424 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7430 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7432 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7435 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7436 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7439 MachinePointerInfo MPI =
7449 if (!MemOps.
empty())
7455SDValue PPCTargetLowering::LowerCall_AIX(
7468 "Unexpected calling convention!");
7470 if (CFlags.IsPatchPoint)
7473 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7477 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7484 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7485 const bool IsPPC64 = Subtarget.isPPC64();
7487 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7488 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7489 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7497 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7498 const unsigned NumBytes = std::max<unsigned>(
7499 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7515 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7516 const unsigned ValNo = ArgLocs[
I].getValNo();
7518 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7520 if (
Flags.isByVal()) {
7521 const unsigned ByValSize =
Flags.getByValSize();
7529 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7535 MachinePointerInfo(), VT);
7538 unsigned LoadOffset = 0;
7541 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7544 LoadOffset += PtrByteSize;
7545 const CCValAssign &ByValVA = ArgLocs[
I++];
7547 "Unexpected location for pass-by-value argument.");
7551 if (LoadOffset == ByValSize)
7555 assert(ArgLocs[
I].getValNo() == ValNo &&
7556 "Expected additional location for by-value argument.");
7558 if (ArgLocs[
I].isMemLoc()) {
7559 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7560 const CCValAssign &ByValVA = ArgLocs[
I++];
7561 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7564 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7570 CallSeqStart, MemcpyFlags, DAG, dl);
7579 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7580 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7581 "Unexpected register residue for by-value argument.");
7583 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7587 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7597 "Unexpected load emitted during handling of pass-by-value "
7605 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7610 const CCValAssign &ByValVA = ArgLocs[
I++];
7615 CCValAssign &VA = ArgLocs[
I++];
7640 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7646 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7648 const unsigned OriginalValNo = VA.
getValNo();
7650 unsigned LoadOffset = 0;
7651 auto HandleCustomVecRegLoc = [&]() {
7652 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7653 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7654 "Expected custom RegLoc.");
7655 CCValAssign RegVA = ArgLocs[
I++];
7657 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7663 LoadOffset += PtrByteSize;
7669 HandleCustomVecRegLoc();
7670 HandleCustomVecRegLoc();
7672 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7673 ArgLocs[
I].getValNo() == OriginalValNo) {
7675 "Only 2 custom RegLocs expected for 64-bit codegen.");
7676 HandleCustomVecRegLoc();
7677 HandleCustomVecRegLoc();
7688 DAG.
getStore(Chain, dl, Arg, PtrOff,
7690 Subtarget.getFrameLowering()->getStackAlign()));
7697 "Unexpected register handling for calling convention.");
7703 "Custom register handling only expected for VarArg.");
7708 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7712 else if (Arg.getValueType().getFixedSizeInBits() <
7720 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7721 "Unexpected custom register for argument!");
7722 CCValAssign &GPR1 = VA;
7731 CCValAssign &PeekArg = ArgLocs[
I];
7734 CCValAssign &GPR2 = ArgLocs[
I++];
7742 if (!MemOpChains.
empty())
7747 if (CFlags.IsIndirect) {
7748 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7749 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7750 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7751 const MVT PtrVT = Subtarget.getScalarIntVT();
7752 const unsigned TOCSaveOffset =
7753 Subtarget.getFrameLowering()->getTOCSaveOffset();
7768 for (
auto Reg : RegsToPass) {
7773 const int SPDiff = 0;
7774 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7775 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7783 const Type *RetTy)
const {
7785 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7786 return CCInfo.CheckReturn(
7801 CCInfo.AnalyzeReturn(Outs,
7810 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7811 CCValAssign &VA = RVLocs[i];
7814 SDValue Arg = OutVals[RealResIdx];
7829 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7830 bool isLittleEndian = Subtarget.isLittleEndian();
7833 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7837 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7852 RetOps.push_back(Glue);
7854 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7858PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7863 EVT IntVT =
Op.getValueType();
7867 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7871 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7883 bool isPPC64 = Subtarget.isPPC64();
7884 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7893 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7899 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7904 bool isPPC64 = Subtarget.isPPC64();
7909 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7915 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7925PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7927 bool isPPC64 = Subtarget.isPPC64();
7932 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7938 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
7961 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7963 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
7965 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
7966 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
7973 bool isPPC64 = Subtarget.isPPC64();
7983 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
7985 Op.getOperand(0),
Op.getOperand(1));
7991 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
7992 Op.getOperand(0),
Op.getOperand(1));
7996 if (
Op.getValueType().isVector())
7997 return LowerVectorLoad(
Op, DAG);
7999 assert(
Op.getValueType() == MVT::i1 &&
8000 "Custom lowering only for i1 loads");
8009 MachineMemOperand *MMO =
LD->getMemOperand();
8013 BasePtr, MVT::i8, MMO);
8021 if (
Op.getOperand(1).getValueType().isVector())
8022 return LowerVectorStore(
Op, DAG);
8024 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8025 "Custom lowering only for i1 stores");
8035 MachineMemOperand *MMO =
ST->getMemOperand();
8044 assert(
Op.getValueType() == MVT::i1 &&
8045 "Custom lowering only for i1 results");
8073 EVT TrgVT =
Op.getValueType();
8097 if (SrcSize == 256) {
8108 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8114 SmallVector<int, 16> ShuffV;
8115 if (Subtarget.isLittleEndian())
8116 for (
unsigned i = 0; i < TrgNumElts; ++i)
8119 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8123 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8136 EVT ResVT =
Op.getValueType();
8137 EVT CmpVT =
Op.getOperand(0).getValueType();
8139 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8145 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8158 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8162 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8179 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8192 if (
LHS.getValueType() == MVT::f32)
8194 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8197 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8205 if (
LHS.getValueType() == MVT::f32)
8207 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8214 if (
LHS.getValueType() == MVT::f32)
8216 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8228 if (
Cmp.getValueType() == MVT::f32)
8230 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8233 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8238 if (
Cmp.getValueType() == MVT::f32)
8240 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8244 if (
Cmp.getValueType() == MVT::f32)
8246 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8250 if (
Cmp.getValueType() == MVT::f32)
8252 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8256 if (
Cmp.getValueType() == MVT::f32)
8258 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8267 case PPCISD::FCTIDZ:
8268 return PPCISD::STRICT_FCTIDZ;
8269 case PPCISD::FCTIWZ:
8270 return PPCISD::STRICT_FCTIWZ;
8271 case PPCISD::FCTIDUZ:
8272 return PPCISD::STRICT_FCTIDUZ;
8273 case PPCISD::FCTIWUZ:
8274 return PPCISD::STRICT_FCTIWUZ;
8276 return PPCISD::STRICT_FCFID;
8277 case PPCISD::FCFIDU:
8278 return PPCISD::STRICT_FCFIDU;
8279 case PPCISD::FCFIDS:
8280 return PPCISD::STRICT_FCFIDS;
8281 case PPCISD::FCFIDUS:
8282 return PPCISD::STRICT_FCFIDUS;
8289 bool IsStrict =
Op->isStrictFPOpcode();
8298 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8300 MVT DestTy =
Op.getSimpleValueType();
8301 assert(Src.getValueType().isFloatingPoint() &&
8302 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8303 DestTy == MVT::i64) &&
8304 "Invalid FP_TO_INT types");
8305 if (Src.getValueType() == MVT::f32) {
8309 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8314 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8320 Opc = IsSigned ? PPCISD::FCTIWZ
8321 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8324 assert((IsSigned || Subtarget.hasFPCVT()) &&
8325 "i64 FP_TO_UINT is supported only with FPCVT");
8326 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8328 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8340void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8342 const SDLoc &dl)
const {
8346 bool IsStrict =
Op->isStrictFPOpcode();
8349 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8350 (IsSigned || Subtarget.hasFPCVT());
8353 MachinePointerInfo MPI =
8361 Alignment =
Align(4);
8362 MachineMemOperand *MMO =
8368 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8372 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8373 !Subtarget.isLittleEndian()) {
8382 RLI.Alignment = Alignment;
8390 const SDLoc &dl)
const {
8393 if (
Op->isStrictFPOpcode())
8400 const SDLoc &dl)
const {
8401 bool IsStrict =
Op->isStrictFPOpcode();
8404 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8405 EVT SrcVT = Src.getValueType();
8406 EVT DstVT =
Op.getValueType();
8409 if (SrcVT == MVT::f128)
8410 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8414 if (SrcVT == MVT::ppcf128) {
8415 if (DstVT == MVT::i32) {
8420 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8431 {Op.getOperand(0), Lo, Hi}, Flags);
8434 {Res.getValue(1), Res}, Flags);
8440 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8464 {Chain, Src, FltOfs}, Flags);
8468 {Chain, Val}, Flags);
8471 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8489 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8490 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8493 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8495 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8496 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8507bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8512 if (
Op->isStrictFPOpcode())
8517 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8521 Op.getOperand(0).getValueType())) {
8523 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8528 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8529 LD->isNonTemporal())
8531 if (
LD->getMemoryVT() != MemVT)
8541 RLI.Ptr =
LD->getBasePtr();
8542 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8544 "Non-pre-inc AM on PPC?");
8549 RLI.Chain =
LD->getChain();
8550 RLI.MPI =
LD->getPointerInfo();
8551 RLI.IsDereferenceable =
LD->isDereferenceable();
8552 RLI.IsInvariant =
LD->isInvariant();
8553 RLI.Alignment =
LD->getAlign();
8554 RLI.AAInfo =
LD->getAAInfo();
8555 RLI.Ranges =
LD->getRanges();
8557 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8564bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8565 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8572 if (!Subtarget.hasP9Vector() &&
8576 for (SDUse &Use : Origin->
uses()) {
8579 if (
Use.getResNo() != 0)
8606 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8607 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8608 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8609 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8610 if (
Op->isStrictFPOpcode()) {
8612 Chain =
Op.getOperand(0);
8614 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8616 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8624 const SDLoc &dl)
const {
8625 assert((
Op.getValueType() == MVT::f32 ||
8626 Op.getValueType() == MVT::f64) &&
8627 "Invalid floating point type as target of conversion");
8628 assert(Subtarget.hasFPCVT() &&
8629 "Int to FP conversions with direct moves require FPCVT");
8630 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8631 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8634 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8653 for (
unsigned i = 1; i < NumConcat; ++i)
8660 const SDLoc &dl)
const {
8661 bool IsStrict =
Op->isStrictFPOpcode();
8662 unsigned Opc =
Op.getOpcode();
8663 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8666 "Unexpected conversion type");
8667 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8668 "Supports conversions to v2f64/v4f32 only.");
8672 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8675 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8680 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8682 SmallVector<int, 16> ShuffV;
8683 for (
unsigned i = 0; i < WideNumElts; ++i)
8686 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8687 int SaveElts = FourEltRes ? 4 : 2;
8688 if (Subtarget.isLittleEndian())
8689 for (
int i = 0; i < SaveElts; i++)
8690 ShuffV[i * Stride] = i;
8692 for (
int i = 1; i <= SaveElts; i++)
8693 ShuffV[i * Stride - 1] = i - 1;
8701 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8702 EVT ExtVT = Src.getValueType();
8703 if (Subtarget.hasP9Altivec())
8714 {Op.getOperand(0), Extend}, Flags);
8716 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8724 bool IsStrict =
Op->isStrictFPOpcode();
8725 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8730 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8732 EVT InVT = Src.getValueType();
8733 EVT OutVT =
Op.getValueType();
8736 return LowerINT_TO_FPVector(
Op, DAG, dl);
8739 if (
Op.getValueType() == MVT::f128)
8740 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8743 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8746 if (Src.getValueType() == MVT::i1) {
8758 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8759 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8760 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8762 assert((IsSigned || Subtarget.hasFPCVT()) &&
8763 "UINT_TO_FP is supported only with FPCVT");
8765 if (Src.getValueType() == MVT::i64) {
8780 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8781 !
Op->getFlags().hasApproximateFuncs()) {
8821 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8822 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8823 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8826 }
else if (Subtarget.hasLFIWAX() &&
8827 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8828 MachineMemOperand *MMO =
8830 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8834 Ops, MVT::i32, MMO);
8837 }
else if (Subtarget.hasFPCVT() &&
8838 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8839 MachineMemOperand *MMO =
8841 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8845 Ops, MVT::i32, MMO);
8848 }
else if (((Subtarget.hasLFIWAX() &&
8850 (Subtarget.hasFPCVT() &&
8865 "Expected an i32 store");
8871 RLI.Alignment =
Align(4);
8873 MachineMemOperand *MMO =
8875 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8878 PPCISD::LFIWZX : PPCISD::LFIWAX,
8879 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8880 Ops, MVT::i32, MMO);
8881 Chain =
Bits.getValue(1);
8889 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8893 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8902 assert(Src.getValueType() == MVT::i32 &&
8903 "Unhandled INT_TO_FP type in custom expander!");
8913 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8916 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8926 "Expected an i32 store");
8932 RLI.Alignment =
Align(4);
8935 MachineMemOperand *MMO =
8937 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8943 if (ReusingLoad && RLI.ResChain) {
8947 assert(Subtarget.isPPC64() &&
8948 "i32->FP without LFIWAX supported only on PPC64");
8957 Chain, dl, Ext64, FIdx,
8963 MVT::f64, dl, Chain, FIdx,
8972 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8976 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
8993 uint64_t
Mode = CVal->getZExtValue();
8994 assert(
Mode < 4 &&
"Unsupported rounding mode!");
8995 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
8996 if (Subtarget.isISA3_0())
8999 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9000 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9003 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9004 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9006 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9024 if (!Subtarget.isISA3_0()) {
9025 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9029 if (Subtarget.isPPC64()) {
9030 if (Subtarget.isISA3_0()) {
9035 PPC::RLDIMI, Dl, MVT::i64,
9040 NewFPSCR =
SDValue(InsertRN, 0);
9047 SDValue Addr = Subtarget.isLittleEndian()
9051 if (Subtarget.isISA3_0()) {
9052 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9054 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9056 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9059 PPC::RLWIMI, Dl, MVT::i32,
9060 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9061 DAG.getTargetConstant(30, Dl, MVT::i32),
9062 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9064 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9067 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9070 if (Subtarget.isISA3_0())
9076 PPC::MTFSF, Dl, MVT::Other,
9104 EVT VT =
Op.getValueType();
9109 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9120 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9124 "Stack slot adjustment is valid only on big endian subtargets!");
9127 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9154 EVT VT =
Op.getValueType();
9158 VT ==
Op.getOperand(1).getValueType() &&
9178 SDValue OutOps[] = { OutLo, OutHi };
9183 EVT VT =
Op.getValueType();
9187 VT ==
Op.getOperand(1).getValueType() &&
9207 SDValue OutOps[] = { OutLo, OutHi };
9213 EVT VT =
Op.getValueType();
9216 VT ==
Op.getOperand(1).getValueType() &&
9236 SDValue OutOps[] = { OutLo, OutHi };
9243 EVT VT =
Op.getValueType();
9250 EVT AmtVT =
Z.getValueType();
9260 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9261 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9273 static const MVT VTys[] = {
9274 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9277 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9280 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9285 EVT CanonicalVT = VTys[SplatSize-1];
9298 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9299 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9308 EVT DestVT = MVT::Other) {
9309 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9318 EVT DestVT = MVT::Other) {
9321 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9333 for (
unsigned i = 0; i != 16; ++i)
9354 EVT VecVT = V->getValueType(0);
9355 bool RightType = VecVT == MVT::v2f64 ||
9356 (HasP8Vector && VecVT == MVT::v4f32) ||
9357 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9361 bool IsSplat =
true;
9362 bool IsLoad =
false;
9368 if (V->isConstant())
9370 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9371 if (V->getOperand(i).isUndef())
9375 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9377 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9379 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9381 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9385 if (V->getOperand(i) != Op0 ||
9386 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9389 return !(IsSplat && IsLoad);
9399 (
Op.getValueType() != MVT::f128))
9404 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9407 if (!Subtarget.isLittleEndian())
9410 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9418 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9419 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9432 APFloat APFloatToConvert = ArgAPFloat;
9433 bool LosesInfo =
true;
9438 ArgAPFloat = APFloatToConvert;
9460 APFloat APFloatToConvert = ArgAPFloat;
9461 bool LosesInfo =
true;
9465 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9474 EVT Ty =
Op->getValueType(0);
9477 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9486 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9490 if (Ty == MVT::v2i64) {
9493 if (MemVT == MVT::i32) {
9495 Opcode = PPCISD::ZEXT_LD_SPLAT;
9497 Opcode = PPCISD::SEXT_LD_SPLAT;
9505 bool IsLittleEndian) {
9511 APInt ConstValue(VTSize, 0);
9515 unsigned BitPos = 0;
9523 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9524 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9528 for (
unsigned J = 0; J < 16; ++J) {
9530 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9532 if (ExtractValue == 0xFF)
9547 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9549 if (Subtarget.hasP10Vector()) {
9550 APInt BitMask(32, 0);
9556 BitMask != 0 && BitMask != 0xffff) {
9558 MachineSDNode *MSDNode =
9570 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9574 APInt APSplatBits, APSplatUndef;
9575 unsigned SplatBitSize;
9577 bool BVNIsConstantSplat =
9579 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9585 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9586 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9589 if ((
Op->getValueType(0) == MVT::v2f64) &&
9592 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9608 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9614 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9622 bool IsSplat64 =
false;
9623 uint64_t SplatBits = 0;
9624 int32_t SextVal = 0;
9625 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9627 if (SplatBitSize <= 32) {
9629 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9630 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9631 bool P9Vector = Subtarget.hasP9Vector();
9632 int32_t
Hi = P9Vector ? 127 : 15;
9633 int32_t
Lo = P9Vector ? -128 : -16;
9634 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9635 SextVal =
static_cast<int32_t
>(SplatBits);
9639 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9640 unsigned NewOpcode = PPCISD::LD_SPLAT;
9646 const SDValue *InputLoad = &
Op.getOperand(0);
9651 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9652 unsigned ElementSize =
9653 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9655 assert(((ElementSize == 2 * MemorySize)
9656 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9657 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9658 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9659 "Unmatched element size and opcode!\n");
9664 unsigned NumUsesOfInputLD = 128 / ElementSize;
9666 if (BVInOp.isUndef())
9681 if (NumUsesOfInputLD == 1 &&
9682 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9683 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9684 Subtarget.hasLFIWAX()))
9692 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9693 Subtarget.isISA3_1() && ElementSize <= 16)
9696 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9698 Subtarget.hasVSX()) {
9705 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9706 LD->getMemoryVT(),
LD->getMemOperand());
9718 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9720 Subtarget.hasP8Vector()))
9726 unsigned SplatSize = SplatBitSize / 8;
9731 if (SplatBits == 0) {
9733 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9745 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9747 Op.getValueType(), DAG, dl);
9749 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9754 if (Subtarget.hasP9Vector() && SplatSize == 1)
9760 if (SextVal >= -16 && SextVal <= 15) {
9763 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9773 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9779 switch (SplatSize) {
9783 IID = Intrinsic::ppc_altivec_vupklsb;
9787 IID = Intrinsic::ppc_altivec_vextsb2w;
9791 IID = Intrinsic::ppc_altivec_vextsb2d;
9798 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9807 if (SextVal >= -32 && SextVal <= 31) {
9812 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9813 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9816 if (VT ==
Op.getValueType())
9825 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9839 static const signed char SplatCsts[] = {
9840 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9841 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9844 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9847 int i = SplatCsts[idx];
9851 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9854 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9856 static const unsigned IIDs[] = {
9857 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9858 Intrinsic::ppc_altivec_vslw
9865 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9867 static const unsigned IIDs[] = {
9868 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9869 Intrinsic::ppc_altivec_vsrw
9876 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9877 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9879 static const unsigned IIDs[] = {
9880 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9881 Intrinsic::ppc_altivec_vrlw
9888 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9890 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9894 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9896 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9900 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9902 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9915 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9916 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9917 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9933 if (LHSID == (1*9+2)*9+3)
return LHS;
9934 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9946 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9947 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9948 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9949 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9952 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9953 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9954 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9955 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9958 for (
unsigned i = 0; i != 16; ++i)
9959 ShufIdxs[i] = (i&3)+0;
9962 for (
unsigned i = 0; i != 16; ++i)
9963 ShufIdxs[i] = (i&3)+4;
9966 for (
unsigned i = 0; i != 16; ++i)
9967 ShufIdxs[i] = (i&3)+8;
9970 for (
unsigned i = 0; i != 16; ++i)
9971 ShufIdxs[i] = (i&3)+12;
9992 const unsigned BytesInVector = 16;
9993 bool IsLE = Subtarget.isLittleEndian();
9997 unsigned ShiftElts = 0, InsertAtByte = 0;
10001 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10002 0, 15, 14, 13, 12, 11, 10, 9};
10003 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10004 1, 2, 3, 4, 5, 6, 7, 8};
10006 ArrayRef<int>
Mask =
N->getMask();
10007 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10019 bool FoundCandidate =
false;
10023 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10026 for (
unsigned i = 0; i < BytesInVector; ++i) {
10027 unsigned CurrentElement =
Mask[i];
10030 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10033 bool OtherElementsInOrder =
true;
10036 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10043 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10044 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10045 OtherElementsInOrder =
false;
10052 if (OtherElementsInOrder) {
10059 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10060 : BigEndianShifts[CurrentElement & 0xF];
10061 Swap = CurrentElement < BytesInVector;
10063 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10064 FoundCandidate =
true;
10069 if (!FoundCandidate)
10079 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10081 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10084 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10093 const unsigned NumHalfWords = 8;
10094 const unsigned BytesInVector = NumHalfWords * 2;
10099 bool IsLE = Subtarget.isLittleEndian();
10103 unsigned ShiftElts = 0, InsertAtByte = 0;
10107 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10108 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10111 uint32_t OriginalOrderLow = 0x1234567;
10112 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10115 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10116 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10133 bool FoundCandidate =
false;
10136 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10137 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10139 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10140 uint32_t TargetOrder = 0x0;
10147 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10148 TargetOrder = OriginalOrderLow;
10152 if (MaskOneElt == VINSERTHSrcElem &&
10153 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10154 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10155 FoundCandidate =
true;
10161 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10163 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10165 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10166 : BigEndianShifts[MaskOneElt & 0x7];
10167 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10168 Swap = MaskOneElt < NumHalfWords;
10169 FoundCandidate =
true;
10175 if (!FoundCandidate)
10187 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10190 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10195 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10210 auto ShuffleMask = SVN->
getMask();
10225 ShuffleMask = CommutedSV->
getMask();
10234 APInt APSplatValue, APSplatUndef;
10235 unsigned SplatBitSize;
10238 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10250 bool IsLE = Subtarget.isLittleEndian();
10251 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10252 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10253 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10255 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10256 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10257 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10265 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10266 SplatVal |= (SplatVal << SplatBitSize);
10269 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10280 assert(
Op.getValueType() == MVT::v1i128 &&
10281 "Only set v1i128 as custom, other type shouldn't reach here!");
10286 if (SHLAmt % 8 == 0) {
10287 std::array<int, 16>
Mask;
10288 std::iota(
Mask.begin(),
Mask.end(), 0);
10289 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10318 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10323 V1 =
Op.getOperand(0);
10324 V2 =
Op.getOperand(1);
10326 EVT VT =
Op.getValueType();
10327 bool isLittleEndian = Subtarget.isLittleEndian();
10329 unsigned ShiftElts, InsertAtByte;
10335 bool IsPermutedLoad =
false;
10337 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10347 if (IsPermutedLoad) {
10348 assert((isLittleEndian || IsFourByte) &&
10349 "Unexpected size for permuted load on big endian target");
10350 SplatIdx += IsFourByte ? 2 : 1;
10351 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10352 "Splat of a value outside of the loaded memory");
10357 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10360 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10362 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10366 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10379 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10382 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10391 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10394 if (Subtarget.hasP9Vector() &&
10404 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10406 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10410 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10415 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10417 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10418 return SplatInsertNode;
10421 if (Subtarget.hasP9Altivec()) {
10423 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10426 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10430 if (Subtarget.hasVSX() &&
10438 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10443 if (Subtarget.hasVSX() &&
10451 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10456 if (Subtarget.hasP9Vector()) {
10476 if (Subtarget.hasVSX()) {
10489 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10497 if (V2.isUndef()) {
10510 (Subtarget.hasP8Altivec() && (
10521 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10531 (Subtarget.hasP8Altivec() && (
10539 ArrayRef<int> PermMask = SVOp->
getMask();
10542 unsigned PFIndexes[4];
10543 bool isFourElementShuffle =
true;
10544 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10546 unsigned EltNo = 8;
10547 for (
unsigned j = 0;
j != 4; ++
j) {
10548 if (PermMask[i * 4 + j] < 0)
10551 unsigned ByteSource = PermMask[i * 4 +
j];
10552 if ((ByteSource & 3) != j) {
10553 isFourElementShuffle =
false;
10558 EltNo = ByteSource / 4;
10559 }
else if (EltNo != ByteSource / 4) {
10560 isFourElementShuffle =
false;
10564 PFIndexes[i] = EltNo;
10572 if (isFourElementShuffle) {
10574 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10575 PFIndexes[2] * 9 + PFIndexes[3];
10578 unsigned Cost = (PFEntry >> 30);
10598 if (V2.isUndef()) V2 = V1;
10600 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10606 unsigned Opcode = PPCISD::VPERM;
10609 bool NeedSwap =
false;
10610 bool isLittleEndian = Subtarget.isLittleEndian();
10611 bool isPPC64 = Subtarget.isPPC64();
10613 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10615 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10616 "XXPERM instead\n");
10617 Opcode = PPCISD::XXPERM;
10625 NeedSwap = !NeedSwap;
10660 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10662 if (V1HasXXSWAPD) {
10665 else if (SrcElt < 16)
10668 if (V2HasXXSWAPD) {
10671 else if (SrcElt > 15)
10680 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10681 if (isLittleEndian)
10683 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10686 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10689 if (V1HasXXSWAPD) {
10693 if (V2HasXXSWAPD) {
10698 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10699 if (ValType != MVT::v2f64)
10705 ShufflesHandledWithVPERM++;
10709 if (Opcode == PPCISD::XXPERM) {
10710 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10712 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10715 dbgs() <<
"With the following permute control vector:\n";
10719 if (Opcode == PPCISD::XXPERM)
10720 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10724 if (isLittleEndian)
10730 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10742 switch (IntrinsicID) {
10746 case Intrinsic::ppc_altivec_vcmpbfp_p:
10750 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10754 case Intrinsic::ppc_altivec_vcmpequb_p:
10758 case Intrinsic::ppc_altivec_vcmpequh_p:
10762 case Intrinsic::ppc_altivec_vcmpequw_p:
10766 case Intrinsic::ppc_altivec_vcmpequd_p:
10767 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10773 case Intrinsic::ppc_altivec_vcmpneb_p:
10774 case Intrinsic::ppc_altivec_vcmpneh_p:
10775 case Intrinsic::ppc_altivec_vcmpnew_p:
10776 case Intrinsic::ppc_altivec_vcmpnezb_p:
10777 case Intrinsic::ppc_altivec_vcmpnezh_p:
10778 case Intrinsic::ppc_altivec_vcmpnezw_p:
10779 if (Subtarget.hasP9Altivec()) {
10780 switch (IntrinsicID) {
10783 case Intrinsic::ppc_altivec_vcmpneb_p:
10786 case Intrinsic::ppc_altivec_vcmpneh_p:
10789 case Intrinsic::ppc_altivec_vcmpnew_p:
10792 case Intrinsic::ppc_altivec_vcmpnezb_p:
10795 case Intrinsic::ppc_altivec_vcmpnezh_p:
10798 case Intrinsic::ppc_altivec_vcmpnezw_p:
10806 case Intrinsic::ppc_altivec_vcmpgefp_p:
10810 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10814 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10818 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10822 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10826 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10827 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10833 case Intrinsic::ppc_altivec_vcmpgtub_p:
10837 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10841 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10845 case Intrinsic::ppc_altivec_vcmpgtud_p:
10846 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10853 case Intrinsic::ppc_altivec_vcmpequq:
10854 case Intrinsic::ppc_altivec_vcmpgtsq:
10855 case Intrinsic::ppc_altivec_vcmpgtuq:
10856 if (!Subtarget.isISA3_1())
10858 switch (IntrinsicID) {
10861 case Intrinsic::ppc_altivec_vcmpequq:
10864 case Intrinsic::ppc_altivec_vcmpgtsq:
10867 case Intrinsic::ppc_altivec_vcmpgtuq:
10874 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10875 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10876 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10877 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10878 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10879 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10880 if (Subtarget.hasVSX()) {
10881 switch (IntrinsicID) {
10882 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10885 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10888 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10891 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10894 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10897 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10907 case Intrinsic::ppc_altivec_vcmpbfp:
10910 case Intrinsic::ppc_altivec_vcmpeqfp:
10913 case Intrinsic::ppc_altivec_vcmpequb:
10916 case Intrinsic::ppc_altivec_vcmpequh:
10919 case Intrinsic::ppc_altivec_vcmpequw:
10922 case Intrinsic::ppc_altivec_vcmpequd:
10923 if (Subtarget.hasP8Altivec())
10928 case Intrinsic::ppc_altivec_vcmpneb:
10929 case Intrinsic::ppc_altivec_vcmpneh:
10930 case Intrinsic::ppc_altivec_vcmpnew:
10931 case Intrinsic::ppc_altivec_vcmpnezb:
10932 case Intrinsic::ppc_altivec_vcmpnezh:
10933 case Intrinsic::ppc_altivec_vcmpnezw:
10934 if (Subtarget.hasP9Altivec())
10935 switch (IntrinsicID) {
10938 case Intrinsic::ppc_altivec_vcmpneb:
10941 case Intrinsic::ppc_altivec_vcmpneh:
10944 case Intrinsic::ppc_altivec_vcmpnew:
10947 case Intrinsic::ppc_altivec_vcmpnezb:
10950 case Intrinsic::ppc_altivec_vcmpnezh:
10953 case Intrinsic::ppc_altivec_vcmpnezw:
10960 case Intrinsic::ppc_altivec_vcmpgefp:
10963 case Intrinsic::ppc_altivec_vcmpgtfp:
10966 case Intrinsic::ppc_altivec_vcmpgtsb:
10969 case Intrinsic::ppc_altivec_vcmpgtsh:
10972 case Intrinsic::ppc_altivec_vcmpgtsw:
10975 case Intrinsic::ppc_altivec_vcmpgtsd:
10976 if (Subtarget.hasP8Altivec())
10981 case Intrinsic::ppc_altivec_vcmpgtub:
10984 case Intrinsic::ppc_altivec_vcmpgtuh:
10987 case Intrinsic::ppc_altivec_vcmpgtuw:
10990 case Intrinsic::ppc_altivec_vcmpgtud:
10991 if (Subtarget.hasP8Altivec())
10996 case Intrinsic::ppc_altivec_vcmpequq_p:
10997 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10998 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10999 if (!Subtarget.isISA3_1())
11001 switch (IntrinsicID) {
11004 case Intrinsic::ppc_altivec_vcmpequq_p:
11007 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11010 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11024 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11030 auto MapNodeWithSplatVector =
11031 [&](
unsigned Opcode,
11032 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11037 Ops.append(ExtraOps.begin(), ExtraOps.end());
11038 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11041 switch (IntrinsicID) {
11042 case Intrinsic::thread_pointer:
11044 if (Subtarget.isPPC64())
11048 case Intrinsic::ppc_rldimi: {
11049 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11051 APInt
Mask =
Op.getConstantOperandAPInt(4);
11053 return Op.getOperand(2);
11054 if (
Mask.isAllOnes())
11056 uint64_t SH =
Op.getConstantOperandVal(3);
11057 unsigned MB = 0, ME = 0;
11061 if (ME < 63 - SH) {
11064 }
else if (ME > 63 - SH) {
11070 {Op.getOperand(2), Src,
11071 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11072 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11076 case Intrinsic::ppc_rlwimi: {
11077 APInt
Mask =
Op.getConstantOperandAPInt(4);
11079 return Op.getOperand(2);
11080 if (
Mask.isAllOnes())
11083 unsigned MB = 0, ME = 0;
11087 PPC::RLWIMI, dl, MVT::i32,
11088 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11089 DAG.getTargetConstant(MB, dl, MVT::i32),
11090 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11094 case Intrinsic::ppc_bcdshift:
11095 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11096 case Intrinsic::ppc_bcdshiftround:
11097 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11098 case Intrinsic::ppc_bcdtruncate:
11099 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11100 case Intrinsic::ppc_bcdunsignedtruncate:
11101 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11102 case Intrinsic::ppc_bcdunsignedshift:
11103 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11105 case Intrinsic::ppc_rlwnm: {
11106 if (
Op.getConstantOperandVal(3) == 0)
11108 unsigned MB = 0, ME = 0;
11113 {Op.getOperand(1), Op.getOperand(2),
11114 DAG.getTargetConstant(MB, dl, MVT::i32),
11115 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11119 case Intrinsic::ppc_mma_disassemble_acc: {
11120 if (Subtarget.isISAFuture()) {
11121 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11132 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11133 Subtarget.isLittleEndian() ? Value2 :
Value,
11134 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11138 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11139 Subtarget.isLittleEndian() ? Value2 :
Value,
11140 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11144 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11145 Subtarget.isLittleEndian() ?
Value : Value2,
11146 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11150 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11151 Subtarget.isLittleEndian() ?
Value : Value2,
11152 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11159 case Intrinsic::ppc_vsx_disassemble_pair: {
11162 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11164 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11167 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11169 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11170 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11178 case Intrinsic::ppc_build_dmr: {
11181 for (
int i = 1; i < 9; i += 2) {
11189 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11196 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11197 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11199 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11200 "Specify P of 0 or 1 for lower or upper 512 bytes");
11201 unsigned HiLo = Idx->getSExtValue();
11205 Opcode = PPC::DMXXEXTFDMR512;
11206 Subx = PPC::sub_wacc_lo;
11208 Opcode = PPC::DMXXEXTFDMR512_HI;
11209 Subx = PPC::sub_wacc_hi;
11212 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11216 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11220 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11221 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11223 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11224 "Specify a dmr row pair 0-3");
11225 unsigned IdxVal = Idx->getSExtValue();
11229 Subx = PPC::sub_dmrrowp0;
11232 Subx = PPC::sub_dmrrowp1;
11235 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11238 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11242 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11248 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11252 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11253 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11255 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11256 "Specify P of 0 or 1 for lower or upper 512 bytes");
11257 unsigned HiLo = Idx->getSExtValue();
11261 Opcode = PPCISD::INST512;
11262 Subx = PPC::sub_wacc_lo;
11264 Opcode = PPCISD::INST512HI;
11265 Subx = PPC::sub_wacc_hi;
11271 Op.getOperand(1), Wacc, SubReg),
11275 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11276 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11278 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11279 "Specify a dmr row pair 0-3");
11280 unsigned IdxVal = Idx->getSExtValue();
11284 Subx = PPC::sub_dmrrowp0;
11287 Subx = PPC::sub_dmrrowp1;
11290 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11293 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11299 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11301 Op.getOperand(1), DMRRowp, SubReg),
11305 case Intrinsic::ppc_mma_xxmfacc:
11306 case Intrinsic::ppc_mma_xxmtacc: {
11308 if (!Subtarget.isISAFuture())
11319 case Intrinsic::ppc_unpack_longdouble: {
11321 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11322 "Argument of long double unpack must be 0 or 1!");
11325 Idx->getValueType(0)));
11328 case Intrinsic::ppc_compare_exp_lt:
11329 case Intrinsic::ppc_compare_exp_gt:
11330 case Intrinsic::ppc_compare_exp_eq:
11331 case Intrinsic::ppc_compare_exp_uo: {
11333 switch (IntrinsicID) {
11334 case Intrinsic::ppc_compare_exp_lt:
11337 case Intrinsic::ppc_compare_exp_gt:
11340 case Intrinsic::ppc_compare_exp_eq:
11343 case Intrinsic::ppc_compare_exp_uo:
11349 PPC::SELECT_CC_I4, dl, MVT::i32,
11350 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11351 Op.getOperand(1), Op.getOperand(2)),
11353 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11354 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11357 case Intrinsic::ppc_test_data_class: {
11358 EVT OpVT =
Op.getOperand(1).getValueType();
11359 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11360 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11373 {Op.getOperand(2), Op.getOperand(1)}),
11375 if (Subtarget.isISA3_1()) {
11382 TestDataClass, SubRegIdx),
11385 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11391 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11392 DAG.getConstant(0, dl, MVT::i32),
11393 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11396 case Intrinsic::ppc_fnmsub: {
11397 EVT VT =
Op.getOperand(1).getValueType();
11398 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11403 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11404 Op.getOperand(2),
Op.getOperand(3));
11406 case Intrinsic::ppc_convert_f128_to_ppcf128:
11407 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11408 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11409 ? RTLIB::CONVERT_PPCF128_F128
11410 : RTLIB::CONVERT_F128_PPCF128;
11412 std::pair<SDValue, SDValue>
Result =
11413 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11417 case Intrinsic::ppc_maxfe:
11418 case Intrinsic::ppc_maxfl:
11419 case Intrinsic::ppc_maxfs:
11420 case Intrinsic::ppc_minfe:
11421 case Intrinsic::ppc_minfl:
11422 case Intrinsic::ppc_minfs: {
11423 EVT VT =
Op.getValueType();
11426 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11427 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11430 if (IntrinsicID == Intrinsic::ppc_minfe ||
11431 IntrinsicID == Intrinsic::ppc_minfl ||
11432 IntrinsicID == Intrinsic::ppc_minfs)
11453 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11454 Op.getOperand(1),
Op.getOperand(2),
11465 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11473 switch (
Op.getConstantOperandVal(1)) {
11478 Bitx = PPC::sub_eq;
11479 SetOp = PPCISD::SETBC;
11484 Bitx = PPC::sub_eq;
11485 SetOp = PPCISD::SETBCR;
11490 Bitx = PPC::sub_lt;
11491 SetOp = PPCISD::SETBC;
11496 Bitx = PPC::sub_lt;
11497 SetOp = PPCISD::SETBCR;
11502 if (Subtarget.isISA3_1()) {
11507 CR6Reg, SubRegIdx, GlueOp),
11509 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11533 unsigned IntrinsicID =
Op.getConstantOperandVal(1);
11535 switch (IntrinsicID) {
11536 case Intrinsic::ppc_amo_lwat_csne:
11537 case Intrinsic::ppc_amo_ldat_csne:
11543 EVT VT = IntrinsicID == Intrinsic::ppc_amo_ldat_csne ? MVT::i64 : MVT::i32;
11550 Args.emplace_back(CmpVal, Ty);
11551 Args.emplace_back(NewVal, Ty);
11552 Args.emplace_back(Ptr, IntPtrTy);
11558 const char *SymName = IntrinsicID == Intrinsic::ppc_amo_ldat_csne
11559 ?
"__ldat_csne_pseudo"
11560 :
"__lwat_csne_pseudo";
11564 TargetLowering::CallLoweringInfo CLI(DAG);
11580 switch (
Op.getConstantOperandVal(ArgStart)) {
11581 case Intrinsic::ppc_cfence: {
11582 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11583 SDValue Val =
Op.getOperand(ArgStart + 1);
11585 if (Ty == MVT::i128) {
11590 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11593 Opcode,
DL, MVT::Other,
11598 case Intrinsic::ppc_disassemble_dmr: {
11600 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11602 case Intrinsic::ppc_amo_stwat:
11603 case Intrinsic::ppc_amo_stdat: {
11606 SDValue Ptr =
Op.getOperand(ArgStart + 1);
11607 SDValue Val =
Op.getOperand(ArgStart + 2);
11610 return DAG.
getNode(PPCISD::STAT, dl, MVT::Other, Chain, Val, Ptr, FC);
11621 if (!Subtarget.isPPC64())
11629 int VectorIndex = 0;
11630 if (Subtarget.isLittleEndian())
11642 "Expecting an atomic compare-and-swap here.");
11645 EVT MemVT = AtomicNode->getMemoryVT();
11663 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11664 Ops.push_back(AtomicNode->getOperand(i));
11666 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11667 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11669 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11676 EVT MemVT =
N->getMemoryVT();
11678 "Expect quadword atomic operations");
11680 unsigned Opc =
N->getOpcode();
11685 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11688 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11689 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11690 Ops.push_back(
N->getOperand(
I));
11692 Ops, MemVT,
N->getMemOperand());
11699 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11706 SDVTList Tys = DAG.
getVTList(MVT::Other);
11709 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11715 Ops.push_back(ValLo);
11716 Ops.push_back(ValHi);
11717 Ops.push_back(
N->getOperand(2));
11719 N->getMemOperand());
11731 enum DataClassMask {
11733 DC_NEG_INF = 1 << 4,
11734 DC_POS_INF = 1 << 5,
11735 DC_NEG_ZERO = 1 << 2,
11736 DC_POS_ZERO = 1 << 3,
11737 DC_NEG_SUBNORM = 1,
11738 DC_POS_SUBNORM = 1 << 1,
11741 EVT VT =
Op.getValueType();
11743 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11744 : VT == MVT::f64 ? PPC::XSTSTDCDP
11755 return DAG.
getNOT(Dl, Rev, MVT::i1);
11762 TestOp, Dl, MVT::i32,
11764 DC_NEG_ZERO | DC_POS_ZERO |
11765 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11771 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11777 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11782 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11795 bool IsQuiet = Mask &
fcQNan;
11801 if (VT == MVT::f128) {
11805 QuietMask = 0x8000;
11806 }
else if (VT == MVT::f64) {
11807 if (Subtarget.isPPC64()) {
11818 QuietMask = 0x80000;
11819 }
else if (VT == MVT::f32) {
11821 QuietMask = 0x400000;
11837 unsigned NativeMask = 0;
11839 NativeMask |= DC_NAN;
11841 NativeMask |= DC_NEG_INF;
11843 NativeMask |= DC_POS_INF;
11845 NativeMask |= DC_NEG_ZERO;
11847 NativeMask |= DC_POS_ZERO;
11849 NativeMask |= DC_NEG_SUBNORM;
11851 NativeMask |= DC_POS_SUBNORM;
11854 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11856 TestOp, Dl, MVT::i32,
11865 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11867 uint64_t RHSC =
Op.getConstantOperandVal(1);
11870 if (
LHS.getValueType() == MVT::ppcf128) {
11894 bool Future = Subtarget.isISAFuture();
11897 "Mask predication not supported");
11900 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11901 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11905 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11908 VPLD->getMemoryVT(), VPLD->getMemOperand());
11915 "Mask predication not supported");
11920 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11921 bool Future = Subtarget.isISAFuture();
11922 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11925 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11928 SDVTList Tys = DAG.
getVTList(MVT::Other);
11931 VPST->getMemoryVT(), VPST->getMemOperand());
11942 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11944 int64_t
IntVal =
Op.getConstantOperandVal(0);
11945 if (IntVal >= -16 && IntVal <= 15)
11951 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11956 MachineMemOperand *MMO =
11958 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11961 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
11965 return Bits.getValue(0);
11981 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11986 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11993 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11994 MachinePointerInfo());
12001 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
12007 "Should only be called for ISD::INSERT_VECTOR_ELT");
12011 EVT VT =
Op.getValueType();
12016 if (VT == MVT::v2f64 &&
C)
12019 if (Subtarget.hasP9Vector()) {
12028 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12034 BitcastLoad,
Op.getOperand(2));
12035 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12039 if (Subtarget.isISA3_1()) {
12040 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12044 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12045 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12055 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12058 unsigned InsertAtElement =
C->getZExtValue();
12059 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12060 if (Subtarget.isLittleEndian()) {
12061 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12063 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
12075 EVT VT =
Op.getValueType();
12076 bool IsV1024i1 = VT == MVT::v1024i1;
12077 bool IsV2048i1 = VT == MVT::v2048i1;
12081 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12083 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12084 "Dense Math support required.");
12085 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12094 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12095 MachineMemOperand *NewMMO =
12103 DAG.
getVTList(MVT::v256i1, MVT::Other),
12104 LoadOps, MVT::v256i1, NewMMO);
12109 if (Subtarget.isLittleEndian()) {
12110 std::reverse(Loads.
begin(), Loads.
end());
12111 std::reverse(LoadChains.
begin(), LoadChains.
end());
12123 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12129 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12132 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12141 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12144 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12149 {RC, Lo, LoSub, Hi, HiSub}),
12159 EVT VT =
Op.getValueType();
12161 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12162 return LowerDMFVectorLoad(
Op, DAG);
12164 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12168 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12169 "Type unsupported without MMA");
12170 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12171 "Type unsupported without paired vector support");
12175 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12184 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12186 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12195 if (Subtarget.isLittleEndian()) {
12196 std::reverse(Loads.
begin(), Loads.
end());
12197 std::reverse(LoadChains.
begin(), LoadChains.
end());
12201 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12217 bool IsV1024i1 = VT == MVT::v1024i1;
12218 bool IsV2048i1 = VT == MVT::v2048i1;
12222 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12224 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12225 "Dense Math support required.");
12226 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12228 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12231 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12236 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12240 MachineSDNode *ExtNode =
12244 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12250 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12256 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12262 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12267 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12272 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12277 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12281 MachineSDNode *ExtNode =
12282 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12286 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12289 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12293 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12298 if (Subtarget.isLittleEndian())
12299 std::reverse(Values.
begin(), Values.
end());
12301 SDVTList Tys = DAG.
getVTList(MVT::Other);
12303 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12307 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12308 MachineMemOperand *NewMMO =
12315 Ops[2] = Values[Idx];
12317 MVT::v256i1, NewMMO);
12333 EVT StoreVT =
Value.getValueType();
12335 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12336 return LowerDMFVectorStore(
Op, DAG);
12338 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12342 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12343 "Type unsupported without MMA");
12344 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12345 "Type unsupported without paired vector support");
12349 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12357 unsigned NumVecs = 2;
12358 if (StoreVT == MVT::v512i1) {
12359 if (Subtarget.isISAFuture()) {
12360 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12362 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12365 Value2 =
SDValue(ExtNode, 1);
12370 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12371 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12373 if (Subtarget.isISAFuture()) {
12374 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12375 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12376 Idx > 1 ? Value2 :
Value,
12379 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12383 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12397 if (
Op.getValueType() == MVT::v4i32) {
12414 LHS,
RHS, DAG, dl, MVT::v4i32);
12417 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12422 }
else if (
Op.getValueType() == MVT::v16i8) {
12424 bool isLittleEndian = Subtarget.isLittleEndian();
12428 LHS,
RHS, DAG, dl, MVT::v8i16);
12433 LHS,
RHS, DAG, dl, MVT::v8i16);
12441 for (
unsigned i = 0; i != 8; ++i) {
12442 if (isLittleEndian) {
12444 Ops[i*2+1] = 2*i+16;
12447 Ops[i*2+1] = 2*i+1+16;
12450 if (isLittleEndian)
12460 bool IsStrict =
Op->isStrictFPOpcode();
12461 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12462 !Subtarget.hasP9Vector())
12472 "Should only be called for ISD::FP_EXTEND");
12476 if (
Op.getValueType() != MVT::v2f64 ||
12477 Op.getOperand(0).getValueType() != MVT::v2f32)
12489 "Node should have 2 operands with second one being a constant!");
12501 int DWord = Idx >> 1;
12504 if (Subtarget.isLittleEndian())
12507 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12521 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12523 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12524 LD->getMemoryVT(),
LD->getMemOperand());
12529 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12534 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12536 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12537 LD->getMemoryVT(),
LD->getMemOperand());
12538 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12549 if (STI.useCRBits())
12566 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12567 if (STI.useCRBits())
12575 SDNode *
N =
Op.getNode();
12576 EVT VT =
N->getValueType(0);
12577 EVT CarryType =
N->getValueType(1);
12578 unsigned Opc =
N->getOpcode();
12580 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12582 N->getOperand(0),
N->getOperand(1));
12594 SDNode *
N =
Op.getNode();
12595 unsigned Opc =
N->getOpcode();
12596 EVT VT =
N->getValueType(0);
12597 EVT CarryType =
N->getValueType(1);
12598 SDValue CarryOp =
N->getOperand(2);
12600 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12606 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12620 EVT VT =
Op.getNode()->getValueType(0);
12646 EVT VT =
Op.getNode()->getValueType(0);
12675 EVT OpVT =
A.getValueType();
12676 EVT ResVT =
Op.getValueType();
12681 if (Subtarget.isPPC64() && OpVT == MVT::i32) {
12691 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12709 switch (
Op.getOpcode()) {
12729 return LowerSSUBO(
Op, DAG);
12731 return LowerSADDO(
Op, DAG);
12743 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12764 return LowerSET_ROUNDING(
Op, DAG);
12771 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12772 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12784 return LowerFP_ROUND(
Op, DAG);
12789 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
12798 return LowerINTRINSIC_VOID(
Op, DAG);
12800 return LowerBSWAP(
Op, DAG);
12802 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12804 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12806 return LowerIS_FPCLASS(
Op, DAG);
12809 return LowerADDSUBO(
Op, DAG);
12812 return LowerADDSUBO_CARRY(
Op, DAG);
12814 return LowerUCMP(
Op, DAG);
12820 if (
Op->getFlags().hasNoFPExcept())
12824 return LowerVP_LOAD(
Op, DAG);
12825 case ISD::VP_STORE:
12826 return LowerVP_STORE(
Op, DAG);
12834 switch (
N->getOpcode()) {
12836 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12853 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12856 assert(
N->getValueType(0) == MVT::i1 &&
12857 "Unexpected result type for CTR decrement intrinsic");
12859 N->getValueType(0));
12869 switch (
N->getConstantOperandVal(0)) {
12870 case Intrinsic::ppc_pack_longdouble:
12872 N->getOperand(2),
N->getOperand(1)));
12874 case Intrinsic::ppc_maxfe:
12875 case Intrinsic::ppc_minfe:
12876 case Intrinsic::ppc_fnmsub:
12877 case Intrinsic::ppc_convert_f128_to_ppcf128:
12884 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12887 EVT VT =
N->getValueType(0);
12889 if (VT == MVT::i64) {
12902 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12906 Results.push_back(LoweredValue);
12907 if (
N->isStrictFPOpcode())
12912 if (!
N->getValueType(0).isVector())
12945 return Builder.CreateIntrinsic(Id, {});
12951 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12953 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12954 "Only 8/16/32/64-bit atomic loads supported");
12960 IntID = Intrinsic::ppc_lbarx;
12961 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12964 IntID = Intrinsic::ppc_lharx;
12965 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12968 IntID = Intrinsic::ppc_lwarx;
12971 IntID = Intrinsic::ppc_ldarx;
12975 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12977 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12988 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12989 "Only 8/16/32/64-bit atomic loads supported");
12995 IntID = Intrinsic::ppc_stbcx;
12996 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12999 IntID = Intrinsic::ppc_sthcx;
13000 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13003 IntID = Intrinsic::ppc_stwcx;
13006 IntID = Intrinsic::ppc_stdcx;
13010 if (SZ == 8 || SZ == 16)
13011 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13013 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13015 return Builder.CreateXor(
Call, Builder.getInt32(1));
13038 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
13048 unsigned AtomicSize,
13049 unsigned BinOpcode,
13050 unsigned CmpOpcode,
13051 unsigned CmpPred)
const {
13055 auto LoadMnemonic = PPC::LDARX;
13056 auto StoreMnemonic = PPC::STDCX;
13057 switch (AtomicSize) {
13061 LoadMnemonic = PPC::LBARX;
13062 StoreMnemonic = PPC::STBCX;
13063 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13066 LoadMnemonic = PPC::LHARX;
13067 StoreMnemonic = PPC::STHCX;
13068 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13071 LoadMnemonic = PPC::LWARX;
13072 StoreMnemonic = PPC::STWCX;
13075 LoadMnemonic = PPC::LDARX;
13076 StoreMnemonic = PPC::STDCX;
13092 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13094 F->insert(It, loopMBB);
13096 F->insert(It, loop2MBB);
13097 F->insert(It, exitMBB);
13103 Register TmpReg = (!BinOpcode) ? incr :
13104 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13105 : &PPC::GPRCRegClass);
13130 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13135 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13137 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13138 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13139 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13169 switch(
MI.getOpcode()) {
13173 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13174 &
MI.getMF()->getRegInfo());
13198 case PPC::EXTSB8_32_64:
13199 case PPC::EXTSB8_rec:
13200 case PPC::EXTSB_rec:
13203 case PPC::EXTSH8_32_64:
13204 case PPC::EXTSH8_rec:
13205 case PPC::EXTSH_rec:
13207 case PPC::EXTSWSLI:
13208 case PPC::EXTSWSLI_32_64:
13209 case PPC::EXTSWSLI_32_64_rec:
13210 case PPC::EXTSWSLI_rec:
13211 case PPC::EXTSW_32:
13212 case PPC::EXTSW_32_64:
13213 case PPC::EXTSW_32_64_rec:
13214 case PPC::EXTSW_rec:
13217 case PPC::SRAWI_rec:
13218 case PPC::SRAW_rec:
13227 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13237 bool IsSignExtended =
13240 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13241 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13242 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13243 .
addReg(
MI.getOperand(3).getReg());
13244 MI.getOperand(3).setReg(ValueReg);
13248 if (Subtarget.hasPartwordAtomics())
13256 bool is64bit = Subtarget.isPPC64();
13257 bool isLittleEndian = Subtarget.isLittleEndian();
13258 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13269 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13271 F->insert(It, loopMBB);
13273 F->insert(It, loop2MBB);
13274 F->insert(It, exitMBB);
13280 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13283 Register PtrReg = RegInfo.createVirtualRegister(RC);
13284 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13286 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13287 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13288 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13289 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13290 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13291 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13292 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13293 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13294 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13295 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13298 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13325 if (ptrA != ZeroReg) {
13326 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13327 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13335 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13336 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13339 .
addImm(is8bit ? 28 : 27);
13340 if (!isLittleEndian)
13341 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13343 .
addImm(is8bit ? 24 : 16);
13345 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13350 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13360 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13364 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13369 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13373 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13376 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13383 Register SReg = RegInfo.createVirtualRegister(GPRC);
13384 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13388 unsigned ValueReg = SReg;
13389 unsigned CmpReg = Incr2Reg;
13390 if (CmpOpcode == PPC::CMPW) {
13391 ValueReg = RegInfo.createVirtualRegister(GPRC);
13392 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13395 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13396 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13398 ValueReg = ValueSReg;
13430 .
addImm(is8bit ? 24 : 16)
13451 Register DstReg =
MI.getOperand(0).getReg();
13453 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13458 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13459 "Invalid Pointer Size!");
13508 Register BufReg =
MI.getOperand(1).getReg();
13510 if (Subtarget.is64BitELFABI()) {
13523 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13525 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13528 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13551 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13554 if (Subtarget.isPPC64()) {
13572 TII->get(PPC::PHI), DstReg)
13576 MI.eraseFromParent();
13590 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13591 "Invalid Pointer Size!");
13594 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13597 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13598 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13612 Register BufReg =
MI.getOperand(0).getReg();
13617 if (PVT == MVT::i64) {
13629 if (PVT == MVT::i64) {
13641 if (PVT == MVT::i64) {
13653 if (PVT == MVT::i64) {
13665 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13675 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13678 MI.eraseFromParent();
13694 "Unexpected stack alignment");
13698 unsigned StackProbeSize =
13701 StackProbeSize &= ~(StackAlign - 1);
13702 return StackProbeSize ? StackProbeSize : StackAlign;
13714 const bool isPPC64 = Subtarget.isPPC64();
13746 MF->
insert(MBBIter, TestMBB);
13747 MF->
insert(MBBIter, BlockMBB);
13748 MF->
insert(MBBIter, TailMBB);
13753 Register DstReg =
MI.getOperand(0).getReg();
13754 Register NegSizeReg =
MI.getOperand(1).getReg();
13766 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13772 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13773 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13775 .
addDef(ActualNegSizeReg)
13777 .
add(
MI.getOperand(2))
13778 .
add(
MI.getOperand(3));
13784 .
addReg(ActualNegSizeReg);
13787 int64_t NegProbeSize = -(int64_t)ProbeSize;
13793 .
addImm(NegProbeSize >> 16);
13797 .
addImm(NegProbeSize & 0xFFFF);
13806 .
addReg(ActualNegSizeReg)
13815 .
addReg(ActualNegSizeReg);
13825 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13852 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13853 MaxCallFrameSizeReg)
13854 .
add(
MI.getOperand(2))
13855 .
add(
MI.getOperand(3));
13856 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13858 .
addReg(MaxCallFrameSizeReg);
13864 MBB->addSuccessor(TestMBB);
13867 MI.eraseFromParent();
13869 ++NumDynamicAllocaProbed;
13874 switch (
MI.getOpcode()) {
13875 case PPC::SELECT_CC_I4:
13876 case PPC::SELECT_CC_I8:
13877 case PPC::SELECT_CC_F4:
13878 case PPC::SELECT_CC_F8:
13879 case PPC::SELECT_CC_F16:
13880 case PPC::SELECT_CC_VRRC:
13881 case PPC::SELECT_CC_VSFRC:
13882 case PPC::SELECT_CC_VSSRC:
13883 case PPC::SELECT_CC_VSRC:
13884 case PPC::SELECT_CC_SPE4:
13885 case PPC::SELECT_CC_SPE:
13893 switch (
MI.getOpcode()) {
13894 case PPC::SELECT_I4:
13895 case PPC::SELECT_I8:
13896 case PPC::SELECT_F4:
13897 case PPC::SELECT_F8:
13898 case PPC::SELECT_F16:
13899 case PPC::SELECT_SPE:
13900 case PPC::SELECT_SPE4:
13901 case PPC::SELECT_VRRC:
13902 case PPC::SELECT_VSFRC:
13903 case PPC::SELECT_VSSRC:
13904 case PPC::SELECT_VSRC:
13914 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13915 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13916 if (Subtarget.is64BitELFABI() &&
13917 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13918 !Subtarget.isUsingPCRelativeCalls()) {
13930 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13931 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13933 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13934 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13948 if (Subtarget.hasISEL() &&
13949 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13950 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13951 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13953 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13954 MI.getOpcode() == PPC::SELECT_CC_I8)
13955 Cond.push_back(
MI.getOperand(4));
13958 Cond.push_back(
MI.getOperand(1));
13961 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13962 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13978 F->insert(It, copy0MBB);
13979 F->insert(It, sinkMBB);
13988 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14003 .
addReg(
MI.getOperand(1).getReg())
14006 unsigned SelectPred =
MI.getOperand(4).getImm();
14009 .
addReg(
MI.getOperand(1).getReg())
14026 .
addReg(
MI.getOperand(3).getReg())
14028 .
addReg(
MI.getOperand(2).getReg())
14030 }
else if (
MI.getOpcode() == PPC::ReadTB) {
14046 F->insert(It, readMBB);
14047 F->insert(It, sinkMBB);
14058 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14066 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14068 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14078 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
14080 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
14082 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
14084 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
14087 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
14089 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
14091 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
14093 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
14096 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
14098 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
14100 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
14102 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14105 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14107 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14109 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14111 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14114 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14116 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14118 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14120 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14123 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14125 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14127 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14129 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14132 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14134 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14136 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14138 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14141 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14143 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14145 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14147 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14150 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14152 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14154 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14156 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14159 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14161 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14163 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14165 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14168 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14170 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14172 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14174 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14176 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14177 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14178 (Subtarget.hasPartwordAtomics() &&
14179 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14180 (Subtarget.hasPartwordAtomics() &&
14181 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14182 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14184 auto LoadMnemonic = PPC::LDARX;
14185 auto StoreMnemonic = PPC::STDCX;
14186 switch (
MI.getOpcode()) {
14189 case PPC::ATOMIC_CMP_SWAP_I8:
14190 LoadMnemonic = PPC::LBARX;
14191 StoreMnemonic = PPC::STBCX;
14192 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14194 case PPC::ATOMIC_CMP_SWAP_I16:
14195 LoadMnemonic = PPC::LHARX;
14196 StoreMnemonic = PPC::STHCX;
14197 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14199 case PPC::ATOMIC_CMP_SWAP_I32:
14200 LoadMnemonic = PPC::LWARX;
14201 StoreMnemonic = PPC::STWCX;
14203 case PPC::ATOMIC_CMP_SWAP_I64:
14204 LoadMnemonic = PPC::LDARX;
14205 StoreMnemonic = PPC::STDCX;
14212 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14213 Register oldval =
MI.getOperand(3).getReg();
14214 Register newval =
MI.getOperand(4).getReg();
14220 F->insert(It, loop1MBB);
14221 F->insert(It, loop2MBB);
14222 F->insert(It, exitMBB);
14243 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14269 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14270 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14274 bool is64bit = Subtarget.isPPC64();
14275 bool isLittleEndian = Subtarget.isLittleEndian();
14276 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14281 Register oldval =
MI.getOperand(3).getReg();
14282 Register newval =
MI.getOperand(4).getReg();
14288 F->insert(It, loop1MBB);
14289 F->insert(It, loop2MBB);
14290 F->insert(It, exitMBB);
14297 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14300 Register PtrReg = RegInfo.createVirtualRegister(RC);
14301 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14303 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14304 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14305 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14306 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14307 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14308 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14309 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14310 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14311 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14312 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14313 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14315 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14316 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14317 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14348 if (ptrA != ZeroReg) {
14349 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14350 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14359 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14360 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14363 .
addImm(is8bit ? 28 : 27);
14364 if (!isLittleEndian)
14365 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14367 .
addImm(is8bit ? 24 : 16);
14369 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14374 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14379 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14382 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14389 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14393 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14396 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14399 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14404 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14421 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14445 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14455 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14470 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14478 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14479 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14480 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14481 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14482 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14483 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14486 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14487 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14490 Register Dest = RegInfo.createVirtualRegister(
14491 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14495 .
addReg(
MI.getOperand(1).getReg())
14498 MI.getOperand(0).getReg())
14499 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14500 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14503 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14506 MI.getOperand(0).getReg())
14508 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14510 unsigned Imm =
MI.getOperand(1).getImm();
14513 MI.getOperand(0).getReg())
14515 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14517 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14521 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14523 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14534 unsigned Mode =
MI.getOperand(1).getImm();
14535 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14539 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14542 }
else if (
MI.getOpcode() == PPC::SETRND) {
14550 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14551 if (Subtarget.hasDirectMove()) {
14552 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14556 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14559 if (RC == &PPC::F8RCRegClass) {
14561 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14562 "Unsupported RegClass.");
14564 StoreOp = PPC::STFD;
14568 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14569 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14570 "Unsupported RegClass.");
14603 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14606 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14618 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14620 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14622 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14623 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14628 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14629 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14634 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14635 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14641 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14642 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14651 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14655 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14657 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14659 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14662 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14668 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14669 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14671 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14678 .
addUse(Src, {}, PPC::sub_gp8_x1);
14681 .
addUse(Src, {}, PPC::sub_gp8_x0);
14682 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14683 MI.getOpcode() == PPC::STQX_PSEUDO) {
14689 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14695 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14696 :
TII->get(PPC::STQ))
14700 }
else if (
MI.getOpcode() == PPC::LWAT_PSEUDO ||
14701 MI.getOpcode() == PPC::LDAT_PSEUDO) {
14703 Register DstReg =
MI.getOperand(0).getReg();
14704 Register PtrReg =
MI.getOperand(1).getReg();
14705 Register ValReg =
MI.getOperand(2).getReg();
14706 unsigned FC =
MI.getOperand(3).getImm();
14707 bool IsLwat =
MI.getOpcode() == PPC::LWAT_PSEUDO;
14710 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
14718 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
14721 .
addImm(PPC::sub_gp8_x0)
14723 .
addImm(PPC::sub_gp8_x1);
14726 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
14732 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14735 .
addReg(Result64, {}, PPC::sub_32);
14739 }
else if (
MI.getOpcode() == PPC::LWAT_COND_PSEUDO ||
14740 MI.getOpcode() == PPC::LDAT_COND_PSEUDO) {
14742 Register DstReg =
MI.getOperand(0).getReg();
14743 Register PtrReg =
MI.getOperand(1).getReg();
14744 unsigned FC =
MI.getOperand(2).getImm();
14745 bool IsLwat_Cond =
MI.getOpcode() == PPC::LWAT_COND_PSEUDO;
14748 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), Pair);
14751 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat_Cond ? PPC::LWAT : PPC::LDAT),
14758 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14761 .
addReg(Result64, {}, PPC::sub_32);
14769 MI.eraseFromParent();
14782 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14785 return RefinementSteps;
14792 EVT VT =
Op.getValueType();
14795 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14819PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14822 EVT VT =
Op.getValueType();
14823 if (VT != MVT::f64 &&
14824 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14827 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14831 int Enabled,
int &RefinementSteps,
14832 bool &UseOneConstNR,
14833 bool Reciprocal)
const {
14835 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14836 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14837 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14838 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14844 UseOneConstNR = !Subtarget.needsTwoConstNR();
14845 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14852 int &RefinementSteps)
const {
14854 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14855 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14856 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14857 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14860 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14876 switch (Subtarget.getCPUDirective()) {
14903 unsigned Bytes,
int Dist,
14917 if (FS != BFS || FS != (
int)Bytes)
return false;
14922 int64_t Offset1 = 0, Offset2 = 0;
14925 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14935 if (isGA1 && isGA2 && GV1 == GV2)
14936 return Offset1 == (Offset2 + Dist*Bytes);
14943 unsigned Bytes,
int Dist,
14946 EVT VT = LS->getMemoryVT();
14953 switch (
N->getConstantOperandVal(1)) {
14954 default:
return false;
14955 case Intrinsic::ppc_altivec_lvx:
14956 case Intrinsic::ppc_altivec_lvxl:
14957 case Intrinsic::ppc_vsx_lxvw4x:
14958 case Intrinsic::ppc_vsx_lxvw4x_be:
14961 case Intrinsic::ppc_vsx_lxvd2x:
14962 case Intrinsic::ppc_vsx_lxvd2x_be:
14965 case Intrinsic::ppc_altivec_lvebx:
14968 case Intrinsic::ppc_altivec_lvehx:
14971 case Intrinsic::ppc_altivec_lvewx:
14981 switch (
N->getConstantOperandVal(1)) {
14982 default:
return false;
14983 case Intrinsic::ppc_altivec_stvx:
14984 case Intrinsic::ppc_altivec_stvxl:
14985 case Intrinsic::ppc_vsx_stxvw4x:
14988 case Intrinsic::ppc_vsx_stxvd2x:
14991 case Intrinsic::ppc_vsx_stxvw4x_be:
14994 case Intrinsic::ppc_vsx_stxvd2x_be:
14997 case Intrinsic::ppc_altivec_stvebx:
15000 case Intrinsic::ppc_altivec_stvehx:
15003 case Intrinsic::ppc_altivec_stvewx:
15020 SDValue Chain = LD->getChain();
15021 EVT VT = LD->getMemoryVT();
15030 while (!Queue.empty()) {
15031 SDNode *ChainNext = Queue.pop_back_val();
15032 if (!Visited.
insert(ChainNext).second)
15039 if (!Visited.
count(ChainLD->getChain().getNode()))
15040 Queue.push_back(ChainLD->getChain().getNode());
15042 for (
const SDUse &O : ChainNext->
ops())
15043 if (!Visited.
count(O.getNode()))
15044 Queue.push_back(O.getNode());
15046 LoadRoots.
insert(ChainNext);
15057 for (
SDNode *
I : LoadRoots) {
15058 Queue.push_back(
I);
15060 while (!Queue.empty()) {
15061 SDNode *LoadRoot = Queue.pop_back_val();
15062 if (!Visited.
insert(LoadRoot).second)
15074 Queue.push_back(U);
15107 auto Final = Shifted;
15118 DAGCombinerInfo &DCI)
const {
15121 SelectionDAG &DAG = DCI.DAG;
15126 if (!DCI.isAfterLegalizeDAG())
15131 for (
const SDNode *U :
N->users())
15136 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15140 if (OpSize <
Size) {
15158 DAGCombinerInfo &DCI)
const {
15159 SelectionDAG &DAG = DCI.DAG;
15162 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15173 N->getValueType(0) != MVT::i1)
15176 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15177 N->getOperand(0).getValueType() != MVT::i64)
15187 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15198 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15221 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15222 N->getOperand(0).getOpcode() !=
ISD::OR &&
15223 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15233 N->getOperand(1).getOpcode() !=
ISD::AND &&
15234 N->getOperand(1).getOpcode() !=
ISD::OR &&
15235 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15246 SmallPtrSet<SDNode *, 16> Visited;
15248 for (
unsigned i = 0; i < 2; ++i) {
15252 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15264 while (!BinOps.
empty()) {
15272 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15306 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15310 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15311 if (User !=
N && !Visited.
count(User))
15320 if (
User->getOperand(0) == Inputs[i])
15323 if (
User->getOperand(0) == Inputs[i] ||
15324 User->getOperand(1) == Inputs[i])
15330 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15331 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15332 if (User !=
N && !Visited.
count(User))
15341 if (
User->getOperand(0) == PromOps[i])
15344 if (
User->getOperand(0) == PromOps[i] ||
15345 User->getOperand(1) == PromOps[i])
15352 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15361 std::list<HandleSDNode> PromOpHandles;
15362 for (
auto &PromOp : PromOps)
15363 PromOpHandles.emplace_back(PromOp);
15370 while (!PromOpHandles.empty()) {
15371 SDValue PromOp = PromOpHandles.back().getValue();
15372 PromOpHandles.pop_back();
15381 PromOpHandles.emplace_front(PromOp);
15395 default:
C = 0;
break;
15408 PromOpHandles.emplace_front(PromOp);
15415 for (
unsigned i = 0; i < 2; ++i)
15425 return N->getOperand(0);
15433 DAGCombinerInfo &DCI)
const {
15434 SelectionDAG &DAG = DCI.DAG;
15451 if (
N->getValueType(0) != MVT::i32 &&
15452 N->getValueType(0) != MVT::i64)
15455 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15456 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15459 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15460 N->getOperand(0).getOpcode() !=
ISD::OR &&
15461 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15468 SmallPtrSet<SDNode *, 16> Visited;
15472 while (!BinOps.
empty()) {
15480 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15506 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15511 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15516 if (User !=
N && !Visited.
count(User))
15522 if (
User->getOperand(0) == Inputs[i])
15523 SelectTruncOp[0].
insert(std::make_pair(User,
15524 User->getOperand(0).getValueType()));
15526 if (
User->getOperand(0) == Inputs[i])
15527 SelectTruncOp[0].
insert(std::make_pair(User,
15528 User->getOperand(0).getValueType()));
15529 if (
User->getOperand(1) == Inputs[i])
15530 SelectTruncOp[1].
insert(std::make_pair(User,
15531 User->getOperand(1).getValueType()));
15536 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15538 if (User !=
N && !Visited.
count(User))
15544 if (
User->getOperand(0) == PromOps[i])
15545 SelectTruncOp[0].
insert(std::make_pair(User,
15546 User->getOperand(0).getValueType()));
15548 if (
User->getOperand(0) == PromOps[i])
15549 SelectTruncOp[0].
insert(std::make_pair(User,
15550 User->getOperand(0).getValueType()));
15551 if (
User->getOperand(1) == PromOps[i])
15552 SelectTruncOp[1].
insert(std::make_pair(User,
15553 User->getOperand(1).getValueType()));
15558 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15559 bool ReallyNeedsExt =
false;
15563 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15568 Inputs[i].getOperand(0).getValueSizeInBits();
15569 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15574 OpBits-PromBits))) ||
15577 (OpBits-(PromBits-1)))) {
15578 ReallyNeedsExt =
true;
15586 std::list<HandleSDNode> PromOpHandles;
15587 for (
auto &PromOp : PromOps)
15588 PromOpHandles.emplace_back(PromOp);
15592 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15599 SDValue InSrc = Inputs[i].getOperand(0);
15617 while (!PromOpHandles.empty()) {
15619 PromOpHandles.pop_back();
15623 default:
C = 0;
break;
15636 PromOpHandles.emplace_front(PromOp);
15646 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15648 PromOpHandles.emplace_front(PromOp);
15656 for (
unsigned i = 0; i < 2; ++i) {
15674 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15675 if (SI0 != SelectTruncOp[0].
end())
15677 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15678 if (SI1 != SelectTruncOp[1].
end())
15687 if (!ReallyNeedsExt)
15688 return N->getOperand(0);
15695 N->getValueSizeInBits(0), PromBits),
15696 dl,
N->getValueType(0)));
15699 "Invalid extension type");
15702 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15712 auto isValidForConvert = [](
SDValue &Operand) {
15731 if (LoadNode->isVolatile())
15752 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15762 "CC mus be ISD::SETNE or ISD::SETEQ");
15764 auto getV16i8Load = [&](
const SDValue &Operand) {
15772 DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15773 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15814 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15815 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15818 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15821 IntrID, CRSel, LHSVec, RHSVec);
15824 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15842 auto IsAndWithOne = [](
SDValue &V) {
15853 auto IsCompareWithZero = [](
SDValue &V) {
15860 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15861 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15878 auto MakeXor1 = [&](
SDValue V) {
15879 EVT VT = V.getValueType();
15886 return MakeXor1(
LHS);
15889 return MakeXor1(
RHS);
15895 DAGCombinerInfo &DCI)
const {
15897 "Should be called with a SETCC node");
15919 SelectionDAG &DAG = DCI.DAG;
15920 EVT VT =
N->getValueType(0);
15921 EVT OpVT =
LHS.getValueType();
15943 return DAGCombineTruncBoolExt(
N, DCI);
15950 Op.getValueType() == MVT::f64;
15962combineElementTruncationToVectorTruncation(
SDNode *
N,
15963 DAGCombinerInfo &DCI)
const {
15965 "Should be called with a BUILD_VECTOR node");
15967 SelectionDAG &DAG = DCI.DAG;
15970 SDValue FirstInput =
N->getOperand(0);
15972 "The input operand must be an fp-to-int conversion.");
15977 if (FirstConversion == PPCISD::FCTIDZ ||
15978 FirstConversion == PPCISD::FCTIDUZ ||
15979 FirstConversion == PPCISD::FCTIWZ ||
15980 FirstConversion == PPCISD::FCTIWUZ) {
15981 bool IsSplat =
true;
15982 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
15983 FirstConversion == PPCISD::FCTIWUZ;
15986 EVT TargetVT =
N->getValueType(0);
15987 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15988 SDValue NextOp =
N->getOperand(i);
15989 if (NextOp.
getOpcode() != PPCISD::MFVSR)
15992 if (NextConversion != FirstConversion)
16000 if (
N->getOperand(i) != FirstInput)
16011 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16012 SDValue In =
N->getOperand(i).getOperand(0);
16022 Ops.push_back(Trunc);
16025 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16029 if (FirstConversion == PPCISD::FCTIDZ ||
16030 FirstConversion == PPCISD::FCTIWZ)
16035 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16037 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16055 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16059 if (FullVal == BasePattern)
16060 return std::make_tuple(Uim,
uint8_t{0});
16063 if (FullVal ==
APInt(128, 1))
16064 return std::make_tuple(Uim,
uint8_t{127});
16066 return std::nullopt;
16086 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16090 EVT VT =
Op.getValueType();
16091 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16105 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16115 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16119 uint64_t ElemValue =
C->getZExtValue();
16123 ElemValue &= ((1ULL << ElemBits) - 1);
16127 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16130 APInt ElemAPInt(128, ElemValue);
16131 ElemAPInt <<= BitPos;
16134 FullVal |= ElemAPInt;
16141 const auto &[Uim, ShiftAmount] = *UIMOpt;
16145 if (ShiftAmount == 0) {
16150 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16151 LxvkqInstr.
dump());
16155 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16167 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16170 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16186 "Should be called with a BUILD_VECTOR node");
16191 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16194 bool InputsAreConsecutiveLoads =
true;
16195 bool InputsAreReverseConsecutive =
true;
16196 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16197 SDValue FirstInput =
N->getOperand(0);
16198 bool IsRoundOfExtLoad =
false;
16208 N->getNumOperands() == 1)
16211 if (!IsRoundOfExtLoad)
16216 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16218 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16221 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16227 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16238 InputsAreConsecutiveLoads =
false;
16240 InputsAreReverseConsecutive =
false;
16243 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16248 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16249 "The loads cannot be both consecutive and reverse consecutive.");
16253 if (InputsAreConsecutiveLoads) {
16254 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16258 ReturnSDVal = WideLoad;
16259 }
else if (InputsAreReverseConsecutive) {
16261 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16266 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16274 for (
auto *LD : InputLoads)
16276 return ReturnSDVal;
16287 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16293 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16295 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16297 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16298 CorrectElems = CorrectElems >> 8;
16299 Elems = Elems >> 8;
16306 EVT VT =
N->getValueType(0);
16310 Input.getValueType().getVectorElementType(),
16344 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16370 Elems = Elems << 8;
16379 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16380 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16387 int TgtElemArrayIdx;
16388 int InputSize =
Input.getValueType().getScalarSizeInBits();
16389 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16390 if (InputSize + OutputSize == 40)
16391 TgtElemArrayIdx = 0;
16392 else if (InputSize + OutputSize == 72)
16393 TgtElemArrayIdx = 1;
16394 else if (InputSize + OutputSize == 48)
16395 TgtElemArrayIdx = 2;
16396 else if (InputSize + OutputSize == 80)
16397 TgtElemArrayIdx = 3;
16398 else if (InputSize + OutputSize == 96)
16399 TgtElemArrayIdx = 4;
16403 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16405 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16406 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16407 if (Elems != CorrectElems) {
16423 if (
N->getValueType(0) != MVT::v1i128)
16426 SDValue Operand =
N->getOperand(0);
16433 EVT MemoryType = LD->getMemoryVT();
16437 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16438 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16441 if (!ValidLDType ||
16447 LD->getChain(), LD->getBasePtr(),
16451 DAG.
getVTList(MVT::v1i128, MVT::Other),
16452 LoadOps, MemoryType, LD->getMemOperand());
16456 DAGCombinerInfo &DCI)
const {
16458 "Should be called with a BUILD_VECTOR node");
16460 SelectionDAG &DAG = DCI.DAG;
16463 if (!Subtarget.hasVSX())
16470 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16471 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16486 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16495 if (Subtarget.isISA3_1()) {
16501 if (
N->getValueType(0) != MVT::v2f64)
16512 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16523 if (!Ext1Op || !Ext2Op)
16532 if (FirstElem == 0 && SecondElem == 1)
16533 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16534 else if (FirstElem == 2 && SecondElem == 3)
16535 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16541 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16542 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16547 DAGCombinerInfo &DCI)
const {
16550 "Need an int -> FP conversion node here");
16555 SelectionDAG &DAG = DCI.DAG;
16561 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16563 if (!
Op.getOperand(0).getValueType().isSimple())
16565 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16566 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16569 SDValue FirstOperand(
Op.getOperand(0));
16570 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16571 (FirstOperand.getValueType() == MVT::i8 ||
16572 FirstOperand.getValueType() == MVT::i16);
16573 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16575 bool DstDouble =
Op.getValueType() == MVT::f64;
16576 unsigned ConvOp =
Signed ?
16577 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16578 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16583 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16586 Ops, MVT::i8, LDN->getMemOperand());
16591 SDValue ExtOps[] = { Ld, WidthConst };
16593 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16595 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16603 if (
Op.getOperand(0).getValueType() == MVT::i32)
16607 "UINT_TO_FP is supported only with FPCVT");
16611 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16616 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16623 Subtarget.hasFPCVT()) ||
16625 SDValue Src =
Op.getOperand(0).getOperand(0);
16626 if (Src.getValueType() == MVT::f32) {
16628 DCI.AddToWorklist(Src.getNode());
16629 }
else if (Src.getValueType() != MVT::f64) {
16641 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16644 DCI.AddToWorklist(
FP.getNode());
16668 switch (
N->getOpcode()) {
16673 Chain = LD->getChain();
16674 Base = LD->getBasePtr();
16675 MMO = LD->getMemOperand();
16694 MVT VecTy =
N->getValueType(0).getSimpleVT();
16702 Chain = Load.getValue(1);
16704 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16708 if (VecTy != MVT::v2f64) {
16735 switch (
N->getOpcode()) {
16740 Chain = ST->getChain();
16741 Base = ST->getBasePtr();
16742 MMO = ST->getMemOperand();
16762 SDValue Src =
N->getOperand(SrcOpnd);
16763 MVT VecTy = Src.getValueType().getSimpleVT();
16766 if (VecTy != MVT::v2f64) {
16772 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16778 StoreOps, VecTy, MMO);
16785 DAGCombinerInfo &DCI)
const {
16788 unsigned Opcode =
N->getOperand(1).getOpcode();
16790 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16794 &&
"Not a FP_TO_INT Instruction!");
16796 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16797 EVT Op1VT =
N->getOperand(1).getValueType();
16800 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16804 bool ValidTypeForStoreFltAsInt =
16805 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16806 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16809 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16812 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16820 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16835 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16836 for (
int i = 1, e = Mask.size(); i < e; i++) {
16837 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16839 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16841 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16852 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16853 FirstOp =
Op.getOperand(i);
16859 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16860 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16870 Op =
Op.getOperand(0);
16886 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16887 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16889 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16891 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16892 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16893 int Idx = ShuffV[
I];
16894 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16895 ShuffV[
I] += LHSEltFixup;
16896 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16897 ShuffV[
I] += RHSEltFixup;
16908 SDLoc dl(OrigSToV);
16911 "Expecting a SCALAR_TO_VECTOR here");
16924 "Cannot produce a permuted scalar_to_vector for one element vector");
16926 unsigned ResultInElt = NumElts / 2;
16932 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
16937 int HalfVec,
int LHSLastElementDefined,
16938 int RHSLastElementDefined) {
16939 for (
int Index : ShuffV) {
16943 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16944 (Index > LHSLastElementDefined))
16947 if ((RHSLastElementDefined >= 0) &&
16948 (Index > HalfVec + RHSLastElementDefined))
16955 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16956 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16972 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16973 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16976 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16977 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16978 return SToVPermuted;
16998 int NumElts =
LHS.getValueType().getVectorNumElements();
17001 bool IsLittleEndian = Subtarget.isLittleEndian();
17008 if (!Subtarget.hasDirectMove())
17028 SmallVector<int, 16> ShuffV(Mask);
17031 if (SToVLHS || SToVRHS) {
17034 int ShuffleNumElts = ShuffV.
size();
17035 int HalfVec = ShuffleNumElts / 2;
17041 unsigned LHSNumValidElts = HalfVec;
17042 unsigned RHSNumValidElts = HalfVec;
17047 int LHSFirstElt = 0;
17048 int RHSFirstElt = ShuffleNumElts;
17049 int LHSLastElt = -1;
17050 int RHSLastElt = -1;
17058 int LHSScalarSize = 0;
17059 int RHSScalarSize = 0;
17062 if (!IsLittleEndian && LHSScalarSize >= 64)
17067 if (!IsLittleEndian && RHSScalarSize >= 64)
17070 if (LHSScalarSize != 0)
17072 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17073 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17074 if (RHSScalarSize != 0)
17076 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17077 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17088 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17089 LHSNumValidElts, RHSNumValidElts, Subtarget);
17115 if (IsLittleEndian) {
17118 if (Mask[0] < NumElts)
17119 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17123 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17128 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17132 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17137 if (Mask[0] < NumElts)
17138 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17142 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17147 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17151 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17161 if (IsLittleEndian)
17170 DAGCombinerInfo &DCI)
const {
17172 "Not a reverse memop pattern!");
17174 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17177 auto I =
Mask.rbegin();
17178 auto E =
Mask.rend();
17180 for (;
I !=
E; ++
I) {
17188 SelectionDAG &DAG = DCI.DAG;
17191 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17197 if (!Subtarget.hasP9Vector())
17200 if(!IsElementReverse(SVN))
17207 for (SDUse &Use : LSBase->
uses())
17208 if (
Use.getResNo() == 0 &&
17215 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17230 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17239 if (IntrinsicID == Intrinsic::ppc_stdcx)
17241 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17243 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17245 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17254 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17258 if (
LHS->getOpcode() == PPCISD::ADDE &&
17310 auto isZeroOrOne = [=](
SDValue &V) {
17312 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17317 if (!isZeroOrOne(NonNullConstant))
17327 EVT VType =
N->getValueType(0);
17331 return NewNonNullConstant;
17350 EVT XorVT =
N->getValueType(0);
17351 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17359 if (!XorConst || !XorConst->
isOne()) {
17361 if (!XorConst || !XorConst->
isOne())
17368 if (!
LHS.hasOneUse())
17376 SelectNode =
LHS.getOperand(0);
17390 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17400 if (!ConstOp1 || !ConstOp2)
17404 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17413 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17415 bool ConstOp1IsOne = ConstOp1->
isOne();
17418 {SelectNode.getOperand(0),
17419 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17420 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17421 SelectNode.getOperand(3)}),
17429 switch (
N->getOpcode()) {
17432 return combineADD(
N, DCI);
17464 return combineSHL(
N, DCI);
17466 return combineSRA(
N, DCI);
17468 return combineSRL(
N, DCI);
17470 return combineMUL(
N, DCI);
17472 case PPCISD::FNMSUB:
17473 return combineFMALike(
N, DCI);
17476 return N->getOperand(0);
17480 return N->getOperand(0);
17486 return N->getOperand(0);
17495 return DAGCombineExtBoolTrunc(
N, DCI);
17497 return combineTRUNCATE(
N, DCI);
17499 if (
SDValue CSCC = combineSetCC(
N, DCI))
17503 return DAGCombineTruncBoolExt(
N, DCI);
17506 return combineFPToIntToFP(
N, DCI);
17515 EVT Op1VT =
N->getOperand(1).getValueType();
17516 unsigned Opcode =
N->getOperand(1).getOpcode();
17520 SDValue Val = combineStoreFPToInt(
N, DCI);
17534 N->getOperand(1).getNode()->hasOneUse() &&
17535 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17536 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17544 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17551 if (Op1VT.
bitsGT(mVT)) {
17556 if (Op1VT == MVT::i64)
17561 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17581 ST->getBasePtr(), ST->getOffset(), MemVT,
17582 ST->getMemOperand(), ST->getAddressingMode(),
17586 return ST->isUnindexed()
17595 if (Subtarget.needsSwapsForVSXMemOps() &&
17596 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17597 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17604 EVT VT = LD->getValueType(0);
17610 if (Subtarget.needsSwapsForVSXMemOps() &&
17611 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17612 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17623 auto ReplaceTwoFloatLoad = [&]() {
17624 if (VT != MVT::i64)
17639 if (!LD->hasNUsesOfValue(2, 0))
17642 auto UI = LD->user_begin();
17643 while (UI.getUse().getResNo() != 0) ++UI;
17645 while (UI.getUse().getResNo() != 0) ++UI;
17646 SDNode *RightShift = *UI;
17654 if (RightShift->getOpcode() !=
ISD::SRL ||
17656 RightShift->getConstantOperandVal(1) != 32 ||
17657 !RightShift->hasOneUse())
17660 SDNode *Trunc2 = *RightShift->user_begin();
17670 Bitcast->getValueType(0) != MVT::f32)
17676 if (Subtarget.isLittleEndian())
17682 SDValue BasePtr = LD->getBasePtr();
17683 if (LD->isIndexed()) {
17685 "Non-pre-inc AM on PPC?");
17693 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17694 LD->getPointerInfo(), LD->getAlign(),
17695 MMOFlags, LD->getAAInfo());
17701 LD->getPointerInfo().getWithOffset(4),
17704 if (LD->isIndexed()) {
17718 if (ReplaceTwoFloatLoad())
17721 EVT MemVT = LD->getMemoryVT();
17724 if (LD->isUnindexed() && VT.
isVector() &&
17727 !Subtarget.hasP8Vector() &&
17728 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17729 VT == MVT::v4f32))) &&
17730 LD->getAlign() < ABIAlignment) {
17732 SDValue Chain = LD->getChain();
17733 SDValue Ptr = LD->getBasePtr();
17734 bool isLittleEndian = Subtarget.isLittleEndian();
17761 MVT PermCntlTy, PermTy, LDTy;
17762 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17763 : Intrinsic::ppc_altivec_lvsl;
17764 IntrLD = Intrinsic::ppc_altivec_lvx;
17765 IntrPerm = Intrinsic::ppc_altivec_vperm;
17766 PermCntlTy = MVT::v16i8;
17767 PermTy = MVT::v4i32;
17786 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
17790 BaseLoadOps, LDTy, BaseMMO);
17799 int IncValue = IncOffset;
17816 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
17820 ExtraLoadOps, LDTy, ExtraMMO);
17831 if (isLittleEndian)
17833 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17836 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17839 Perm = Subtarget.hasAltivec()
17854 bool isLittleEndian = Subtarget.isLittleEndian();
17855 unsigned IID =
N->getConstantOperandVal(0);
17856 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17857 : Intrinsic::ppc_altivec_lvsl);
17858 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17865 .zext(
Add.getScalarValueSizeInBits()))) {
17866 SDNode *BasePtr =
Add->getOperand(0).getNode();
17867 for (
SDNode *U : BasePtr->users()) {
17869 U->getConstantOperandVal(0) == IID) {
17880 SDNode *BasePtr =
Add->getOperand(0).getNode();
17881 for (
SDNode *U : BasePtr->users()) {
17884 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17890 V->getConstantOperandVal(0) == IID) {
17902 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17903 IID == Intrinsic::ppc_altivec_vmaxsh ||
17904 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17935 switch (
N->getConstantOperandVal(1)) {
17938 case Intrinsic::ppc_altivec_vsum4sbs:
17939 case Intrinsic::ppc_altivec_vsum4shs:
17940 case Intrinsic::ppc_altivec_vsum4ubs: {
17947 APInt APSplatBits, APSplatUndef;
17948 unsigned SplatBitSize;
17951 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17952 !Subtarget.isLittleEndian());
17954 if (BVNIsConstantSplat && APSplatBits == 0)
17959 case Intrinsic::ppc_vsx_lxvw4x:
17960 case Intrinsic::ppc_vsx_lxvd2x:
17963 if (Subtarget.needsSwapsForVSXMemOps())
17971 if (Subtarget.needsSwapsForVSXMemOps()) {
17972 switch (
N->getConstantOperandVal(1)) {
17975 case Intrinsic::ppc_vsx_stxvw4x:
17976 case Intrinsic::ppc_vsx_stxvd2x:
17985 bool Is64BitBswapOn64BitTgt =
17986 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17988 N->getOperand(0).hasOneUse();
17989 if (IsSingleUseNormalLd &&
17990 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17991 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18002 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18003 MVT::i64 : MVT::i32, MVT::Other),
18004 Ops, LD->getMemoryVT(), LD->getMemOperand());
18008 if (
N->getValueType(0) == MVT::i16)
18025 !IsSingleUseNormalLd)
18030 if (!LD->isSimple())
18032 SDValue BasePtr = LD->getBasePtr();
18034 LD->getPointerInfo(), LD->getAlign());
18039 LD->getMemOperand(), 4, 4);
18043 if (Subtarget.isLittleEndian())
18049 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18058 if (!
N->getOperand(0).hasOneUse() &&
18059 !
N->getOperand(1).hasOneUse() &&
18060 !
N->getOperand(2).hasOneUse()) {
18063 SDNode *VCMPrecNode =
nullptr;
18065 SDNode *LHSN =
N->getOperand(0).getNode();
18067 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18071 VCMPrecNode =
User;
18083 SDNode *FlagUser =
nullptr;
18085 FlagUser ==
nullptr; ++UI) {
18086 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18099 return SDValue(VCMPrecNode, 0);
18110 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18121 auto RHSAPInt = RHS->getAsAPIntVal();
18122 if (!RHSAPInt.isIntN(64))
18125 unsigned Val = RHSAPInt.getZExtValue();
18126 auto isImpossibleCompare = [&]() {
18129 if (Val != 0 && Val != 1) {
18131 return N->getOperand(0);
18134 N->getOperand(0),
N->getOperand(4));
18139 unsigned StoreWidth = 0;
18142 if (
SDValue Impossible = isImpossibleCompare())
18154 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18158 PPCISD::STORE_COND, dl,
18160 MemNode->getMemoryVT(), MemNode->getMemOperand());
18164 if (
N->getOperand(0) == LHS.getValue(1))
18175 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18177 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18183 assert(isDot &&
"Can't compare against a vector result!");
18185 if (
SDValue Impossible = isImpossibleCompare())
18188 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18195 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18200 switch (LHS.getConstantOperandVal(1)) {
18216 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18219 N->getOperand(4), CompNode.
getValue(1));
18224 return DAGCombineBuildVector(
N, DCI);
18237 EVT VT =
N->getValueType(0);
18238 if (VT == MVT::i64 && !Subtarget.isPPC64())
18240 if ((VT != MVT::i32 && VT != MVT::i64) ||
18248 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18268 const APInt &DemandedElts,
18270 unsigned Depth)
const {
18272 switch (
Op.getOpcode()) {
18274 case PPCISD::LBRX: {
18277 Known.
Zero = 0xFFFF0000;
18280 case PPCISD::ADDE: {
18281 if (
Op.getResNo() == 0) {
18286 Known.
Zero = ~1ULL;
18291 switch (
Op.getConstantOperandVal(0)) {
18293 case Intrinsic::ppc_altivec_vcmpbfp_p:
18294 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18295 case Intrinsic::ppc_altivec_vcmpequb_p:
18296 case Intrinsic::ppc_altivec_vcmpequh_p:
18297 case Intrinsic::ppc_altivec_vcmpequw_p:
18298 case Intrinsic::ppc_altivec_vcmpequd_p:
18299 case Intrinsic::ppc_altivec_vcmpequq_p:
18300 case Intrinsic::ppc_altivec_vcmpgefp_p:
18301 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18302 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18303 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18304 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18305 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18306 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18307 case Intrinsic::ppc_altivec_vcmpgtub_p:
18308 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18309 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18310 case Intrinsic::ppc_altivec_vcmpgtud_p:
18311 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18318 switch (
Op.getConstantOperandVal(1)) {
18321 case Intrinsic::ppc_load2r:
18323 Known.
Zero = 0xFFFF0000;
18332 switch (Subtarget.getCPUDirective()) {
18354 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18363 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18365 LoopSize +=
TII->getInstSizeInBytes(J);
18370 if (LoopSize > 16 && LoopSize <= 32)
18384 if (Constraint.
size() == 1) {
18385 switch (Constraint[0]) {
18403 }
else if (Constraint ==
"wc") {
18405 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18406 Constraint ==
"wf" || Constraint ==
"ws" ||
18407 Constraint ==
"wi" || Constraint ==
"ww") {
18420 Value *CallOperandVal =
info.CallOperandVal;
18423 if (!CallOperandVal)
18430 else if ((
StringRef(constraint) ==
"wa" ||
18442 switch (*constraint) {
18472std::pair<unsigned, const TargetRegisterClass *>
18476 if (Constraint.
size() == 1) {
18478 switch (Constraint[0]) {
18480 if (VT == MVT::i64 && Subtarget.isPPC64())
18481 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18482 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18484 if (VT == MVT::i64 && Subtarget.isPPC64())
18485 return std::make_pair(0U, &PPC::G8RCRegClass);
18486 return std::make_pair(0U, &PPC::GPRCRegClass);
18492 if (Subtarget.hasSPE()) {
18493 if (VT == MVT::f32 || VT == MVT::i32)
18494 return std::make_pair(0U, &PPC::GPRCRegClass);
18495 if (VT == MVT::f64 || VT == MVT::i64)
18496 return std::make_pair(0U, &PPC::SPERCRegClass);
18498 if (VT == MVT::f32 || VT == MVT::i32)
18499 return std::make_pair(0U, &PPC::F4RCRegClass);
18500 if (VT == MVT::f64 || VT == MVT::i64)
18501 return std::make_pair(0U, &PPC::F8RCRegClass);
18505 if (Subtarget.hasAltivec() && VT.
isVector())
18506 return std::make_pair(0U, &PPC::VRRCRegClass);
18507 else if (Subtarget.hasVSX())
18509 return std::make_pair(0U, &PPC::VFRCRegClass);
18512 return std::make_pair(0U, &PPC::CRRCRegClass);
18514 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18516 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18517 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18518 Constraint ==
"wf" || Constraint ==
"wi") &&
18519 Subtarget.hasVSX()) {
18523 return std::make_pair(0U, &PPC::VSRCRegClass);
18524 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18525 return std::make_pair(0U, &PPC::VSSRCRegClass);
18526 return std::make_pair(0U, &PPC::VSFRCRegClass);
18527 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18528 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18529 return std::make_pair(0U, &PPC::VSSRCRegClass);
18531 return std::make_pair(0U, &PPC::VSFRCRegClass);
18532 }
else if (Constraint ==
"lr") {
18533 if (VT == MVT::i64)
18534 return std::make_pair(0U, &PPC::LR8RCRegClass);
18536 return std::make_pair(0U, &PPC::LRRCRegClass);
18541 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18545 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18546 int VSNum = atoi(Constraint.
data() + 3);
18547 assert(VSNum >= 0 && VSNum <= 63 &&
18548 "Attempted to access a vsr out of range");
18550 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18551 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18556 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18557 int RegNum = atoi(Constraint.
data() + 2);
18558 if (RegNum > 31 || RegNum < 0)
18560 if (VT == MVT::f32 || VT == MVT::i32)
18561 return Subtarget.hasSPE()
18562 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18563 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18564 if (VT == MVT::f64 || VT == MVT::i64)
18565 return Subtarget.hasSPE()
18566 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18567 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18571 std::pair<unsigned, const TargetRegisterClass *> R =
18580 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18581 PPC::GPRCRegClass.contains(R.first))
18582 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18583 PPC::sub_32, &PPC::G8RCRegClass),
18584 &PPC::G8RCRegClass);
18587 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18588 R.first = PPC::CR0;
18589 R.second = &PPC::CRRCRegClass;
18593 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18594 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18595 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18596 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18597 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18598 "default AIX AltiVec ABI and cannot be used\n";
18608 std::vector<SDValue> &
Ops,
18613 if (Constraint.
size() > 1)
18616 char Letter = Constraint[0];
18631 EVT TCVT = MVT::i64;
18672 if (Result.getNode()) {
18673 Ops.push_back(Result);
18684 if (
I.getNumOperands() <= 1)
18688 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18689 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18690 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18693 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18709 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18721 switch (AM.
Scale) {
18749 unsigned Depth =
Op.getConstantOperandVal(0);
18773 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18781 unsigned Depth =
Op.getConstantOperandVal(0);
18788 bool isPPC64 = PtrVT == MVT::i64;
18794 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18796 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18802 FrameAddr, MachinePointerInfo());
18806#define GET_REGISTER_MATCHER
18807#include "PPCGenAsmMatcher.inc"
18811 bool IsPPC64 = Subtarget.isPPC64();
18823 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18829 Reg = Reg.id() - PPC::R0 + PPC::X0;
18836 if (Subtarget.is32BitELFABI())
18841 if (Subtarget.isAIXABI())
18855 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18871 case Intrinsic::ppc_atomicrmw_xchg_i128:
18872 case Intrinsic::ppc_atomicrmw_add_i128:
18873 case Intrinsic::ppc_atomicrmw_sub_i128:
18874 case Intrinsic::ppc_atomicrmw_nand_i128:
18875 case Intrinsic::ppc_atomicrmw_and_i128:
18876 case Intrinsic::ppc_atomicrmw_or_i128:
18877 case Intrinsic::ppc_atomicrmw_xor_i128:
18878 case Intrinsic::ppc_cmpxchg_i128:
18880 Info.memVT = MVT::i128;
18881 Info.ptrVal =
I.getArgOperand(0);
18883 Info.align =
Align(16);
18888 case Intrinsic::ppc_atomic_load_i128:
18890 Info.memVT = MVT::i128;
18891 Info.ptrVal =
I.getArgOperand(0);
18893 Info.align =
Align(16);
18897 case Intrinsic::ppc_atomic_store_i128:
18899 Info.memVT = MVT::i128;
18900 Info.ptrVal =
I.getArgOperand(2);
18902 Info.align =
Align(16);
18906 case Intrinsic::ppc_altivec_lvx:
18907 case Intrinsic::ppc_altivec_lvxl:
18908 case Intrinsic::ppc_altivec_lvebx:
18909 case Intrinsic::ppc_altivec_lvehx:
18910 case Intrinsic::ppc_altivec_lvewx:
18911 case Intrinsic::ppc_vsx_lxvd2x:
18912 case Intrinsic::ppc_vsx_lxvw4x:
18913 case Intrinsic::ppc_vsx_lxvd2x_be:
18914 case Intrinsic::ppc_vsx_lxvw4x_be:
18915 case Intrinsic::ppc_vsx_lxvl:
18916 case Intrinsic::ppc_vsx_lxvll: {
18919 case Intrinsic::ppc_altivec_lvebx:
18922 case Intrinsic::ppc_altivec_lvehx:
18925 case Intrinsic::ppc_altivec_lvewx:
18928 case Intrinsic::ppc_vsx_lxvd2x:
18929 case Intrinsic::ppc_vsx_lxvd2x_be:
18939 Info.ptrVal =
I.getArgOperand(0);
18942 Info.align =
Align(1);
18947 case Intrinsic::ppc_altivec_stvx:
18948 case Intrinsic::ppc_altivec_stvxl:
18949 case Intrinsic::ppc_altivec_stvebx:
18950 case Intrinsic::ppc_altivec_stvehx:
18951 case Intrinsic::ppc_altivec_stvewx:
18952 case Intrinsic::ppc_vsx_stxvd2x:
18953 case Intrinsic::ppc_vsx_stxvw4x:
18954 case Intrinsic::ppc_vsx_stxvd2x_be:
18955 case Intrinsic::ppc_vsx_stxvw4x_be:
18956 case Intrinsic::ppc_vsx_stxvl:
18957 case Intrinsic::ppc_vsx_stxvll: {
18960 case Intrinsic::ppc_altivec_stvebx:
18963 case Intrinsic::ppc_altivec_stvehx:
18966 case Intrinsic::ppc_altivec_stvewx:
18969 case Intrinsic::ppc_vsx_stxvd2x:
18970 case Intrinsic::ppc_vsx_stxvd2x_be:
18980 Info.ptrVal =
I.getArgOperand(1);
18983 Info.align =
Align(1);
18988 case Intrinsic::ppc_stdcx:
18989 case Intrinsic::ppc_stwcx:
18990 case Intrinsic::ppc_sthcx:
18991 case Intrinsic::ppc_stbcx: {
18993 auto Alignment =
Align(8);
18995 case Intrinsic::ppc_stdcx:
18998 case Intrinsic::ppc_stwcx:
19000 Alignment =
Align(4);
19002 case Intrinsic::ppc_sthcx:
19004 Alignment =
Align(2);
19006 case Intrinsic::ppc_stbcx:
19008 Alignment =
Align(1);
19013 Info.ptrVal =
I.getArgOperand(0);
19015 Info.align = Alignment;
19029 const AttributeList &FuncAttributes)
const {
19033 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19034 if (
Op.isMemset() && Subtarget.hasVSX()) {
19039 if (TailSize > 2 && TailSize <= 4) {
19044 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19049 if (Subtarget.isPPC64()) {
19060 assert(Ty->isIntegerTy());
19062 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19063 return !(BitSize == 0 || BitSize > 64);
19071 return NumBits1 == 64 && NumBits2 == 32;
19079 return NumBits1 == 64 && NumBits2 == 32;
19086 EVT MemVT = LD->getMemoryVT();
19087 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19088 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19104 "invalid fpext types");
19106 if (DestVT == MVT::f128)
19121 unsigned *
Fast)
const {
19135 !Subtarget.allowsUnalignedFPAccess())
19139 if (Subtarget.hasVSX()) {
19140 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19141 VT != MVT::v4f32 && VT != MVT::v4i32)
19148 if (VT == MVT::ppcf128)
19163 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19171 int64_t Imm = ConstNode->getSExtValue();
19192 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19194 switch (Ty->getScalarType()->getTypeID()) {
19199 return Subtarget.hasP9Vector();
19207 if (!
I->hasOneUse())
19211 assert(
User &&
"A single use instruction with no uses.");
19213 switch (
I->getOpcode()) {
19214 case Instruction::FMul: {
19216 if (
User->getOpcode() != Instruction::FSub &&
19217 User->getOpcode() != Instruction::FAdd)
19224 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19225 User->getFastMathFlags().allowContract();
19231 case Instruction::Load: {
19244 if (
User->getOpcode() != Instruction::Store)
19264 static const MCPhysReg ScratchRegs[] = {
19265 PPC::X12, PPC::LR8, PPC::CTR8, 0
19268 return ScratchRegs;
19272 const Constant *PersonalityFn)
const {
19273 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19277 const Constant *PersonalityFn)
const {
19278 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19283 EVT VT ,
unsigned DefinedValues)
const {
19284 if (VT == MVT::v2i64)
19285 return Subtarget.hasDirectMove();
19287 if (Subtarget.hasVSX())
19314 return PPCISD::FNMSUB;
19315 case PPCISD::FNMSUB:
19321 bool LegalOps,
bool OptForSize,
19323 unsigned Depth)
const {
19327 unsigned Opc =
Op.getOpcode();
19328 EVT VT =
Op.getValueType();
19332 case PPCISD::FNMSUB:
19352 if (Flags.hasNoSignedZeros()) {
19356 N0Cost,
Depth + 1);
19360 N1Cost,
Depth + 1);
19362 if (NegN0 && N0Cost <= N1Cost) {
19363 Cost = std::min(N0Cost, N2Cost);
19365 }
else if (NegN1) {
19366 Cost = std::min(N1Cost, N2Cost);
19386 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19392 bool ForCodeSize)
const {
19393 if (!VT.
isSimple() || !Subtarget.hasVSX())
19403 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19408 APSInt IntResult(16,
false);
19413 if (IsExact && IntResult <= 15 && IntResult >= -16)
19415 return Imm.isZero();
19418 return Imm.isPosZero();
19430 unsigned Opcode =
N->getOpcode();
19450 if (Mask->getZExtValue() == OpSizeInBits - 1)
19457 DAGCombinerInfo &DCI)
const {
19458 EVT VT =
N->getValueType(0);
19461 unsigned Opc =
N->getOpcode();
19463 "Unexpected opcode.");
19470 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19474 uint64_t SplatBits = 0;
19475 bool AddSplatCase =
false;
19479 AddSplatCase =
true;
19483 if (!AddSplatCase) {
19487 unsigned SplatBitSize;
19489 APInt APSplatBits, APSplatUndef;
19491 bool BVNIsConstantSplat =
19493 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19494 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19505 if (SplatBits == (EltBits - 1)) {
19509 NewOpc = PPCISD::SHL;
19512 NewOpc = PPCISD::SRL;
19515 NewOpc = PPCISD::SRA;
19519 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19527 if (EltTy != MVT::i64 || SplatBits != 1)
19530 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19533SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19537 if (
N->getValueType(0).isVector())
19538 return combineVectorShift(
N, DCI);
19542 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19545 N->getValueType(0) != MVT::i64)
19560 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19566SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19570 if (
N->getValueType(0).isVector())
19571 return combineVectorShift(
N, DCI);
19576SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19580 if (
N->getValueType(0).isVector())
19581 return combineVectorShift(
N, DCI);
19592 if (!Subtarget.isPPC64())
19598 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19600 Op.getValueType() != MVT::i64)
19604 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19605 Cmp.getOperand(0).getValueType() != MVT::i64)
19609 int64_t NegConstant = 0 -
Constant->getSExtValue();
19618 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19619 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19622 if (LHSHasPattern && !RHSHasPattern)
19624 else if (!LHSHasPattern && !RHSHasPattern)
19628 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19631 SDValue Z = Cmp.getOperand(0);
19633 int64_t NegConstant = 0 -
Constant->getSExtValue();
19646 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19664 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19694 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19697 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19705 if (!GSDN || !ConstNode)
19733 EVT VT =
N->getValueType(0);
19734 if (!Subtarget.hasVSX())
19738 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19750 unsigned NumOfEles =
RHS.getNumOperands();
19751 for (
unsigned i = 0; i < NumOfEles; ++i) {
19753 if (!CN || CN->getSExtValue() != 1)
19768SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19790 DAGCombinerInfo &DCI)
const {
19792 if (Subtarget.useCRBits()) {
19794 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19795 return CRTruncValue;
19802 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19805 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19815 EltToExtract = EltToExtract ? 0 : 1;
19825 return DCI.DAG.getNode(
19827 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19832SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19833 SelectionDAG &DAG = DCI.DAG;
19836 if (!ConstOpOrElement)
19844 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19845 switch (this->Subtarget.getCPUDirective()) {
19868 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19872 EVT VT =
N->getValueType(0);
19877 APInt MulAmtAbs = MulAmt.
abs();
19879 if ((MulAmtAbs - 1).isPowerOf2()) {
19883 if (!IsProfitable(IsNeg,
true, VT))
19896 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19900 if (!IsProfitable(IsNeg,
false, VT))
19921 DAGCombinerInfo &DCI)
const {
19925 SDNodeFlags
Flags =
N->getFlags();
19926 EVT VT =
N->getValueType(0);
19927 SelectionDAG &DAG = DCI.DAG;
19928 unsigned Opc =
N->getOpcode();
19930 bool LegalOps = !DCI.isBeforeLegalizeOps();
19938 if (!
Flags.hasNoSignedZeros())
19954bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19956 if (!Subtarget.is64BitELFABI())
19966 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19971 if (!Callee ||
Callee->isVarArg())
19984bool PPCTargetLowering::
19985isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19990 if (CI->getBitWidth() > 64)
19992 int64_t ConstVal = CI->getZExtValue();
19994 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20003PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20009 if ((Flags & FlagSet) == FlagSet)
20012 if ((Flags & FlagSet) == FlagSet)
20015 if ((Flags & FlagSet) == FlagSet)
20018 if ((Flags & FlagSet) == FlagSet)
20039 if ((FrameIndexAlign % 4) != 0)
20040 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20041 if ((FrameIndexAlign % 16) != 0)
20042 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20046 if ((FrameIndexAlign % 4) == 0)
20048 if ((FrameIndexAlign % 16) == 0)
20061 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20062 if ((Imm & 0x3) == 0)
20064 if ((Imm & 0xf) == 0)
20070 const APInt &ConstImm = CN->getAPIntValue();
20089 const APInt &ConstImm = CN->getAPIntValue();
20099 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20110 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20119unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20124 if (!Subtarget.hasP9Vector())
20129 if (Subtarget.hasPrefixInstrs())
20132 if (Subtarget.hasSPE())
20141 unsigned ParentOp = Parent->
getOpcode();
20145 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20146 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20158 if (LSB->isIndexed())
20164 assert(MN &&
"Parent should be a MemSDNode!");
20169 "Not expecting scalar integers larger than 16 bytes!");
20172 else if (
Size == 32)
20179 else if (
Size == 256) {
20180 assert(Subtarget.pairedVectorMemops() &&
20181 "256-bit vectors are only available when paired vector memops is "
20189 else if (MemVT == MVT::f128 || MemVT.
isVector())
20220 FlagSet &= ~PPC::MOF_NoExt;
20225 bool IsNonP1034BitConst =
20229 IsNonP1034BitConst)
20242 int16_t ForceXFormImm = 0;
20245 Disp =
N.getOperand(0);
20246 Base =
N.getOperand(1);
20257 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20258 Disp =
N.getOperand(0);
20259 Base =
N.getOperand(1);
20264 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20273 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20279 if (PartVT == MVT::f64 &&
20280 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20289SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20293 EVT RetVT =
Op.getValueType();
20300 EVT ArgVT =
N.getValueType();
20304 Entry.IsZExt = !Entry.IsSExt;
20305 Args.push_back(Entry);
20313 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20326SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20327 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20329 if (
Op.getValueType() == MVT::f32)
20330 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20332 if (
Op.getValueType() == MVT::f64)
20333 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20338bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20339 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20340 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20344bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20345 return Op.getNode()->getFlags().hasApproximateFuncs();
20348bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20352SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20353 const char *LibCallFloatName,
20354 const char *LibCallDoubleNameFinite,
20355 const char *LibCallFloatNameFinite,
20358 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20361 if (!isLowringToMASSFiniteSafe(
Op))
20362 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20365 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20366 LibCallDoubleNameFinite,
Op, DAG);
20370 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20371 "__xl_powf_finite",
Op, DAG);
20375 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20376 "__xl_sinf_finite",
Op, DAG);
20380 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20381 "__xl_cosf_finite",
Op, DAG);
20385 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20386 "__xl_logf_finite",
Op, DAG);
20390 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20391 "__xl_log10f_finite",
Op, DAG);
20395 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20396 "__xl_expf_finite",
Op, DAG);
20421 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20432 assert(Subtarget.isUsingPCRelativeCalls() &&
20433 "Must be using PC-Relative calls when a valid PC-Relative node is "
20463 Disp =
N.getOperand(1).getOperand(0);
20468 Base =
N.getOperand(0);
20476 EVT CNType = CN->getValueType(0);
20477 uint64_t CNImm = CN->getZExtValue();
20488 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20490 int32_t Addr = (int32_t)CNImm;
20495 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20511 unsigned Opcode =
N.getOpcode();
20519 Base =
N.getOperand(0);
20538 Base = FI ?
N :
N.getOperand(1);
20539 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20550 bool IsVarArg)
const {
20560 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20597 return Intrinsic::ppc_atomicrmw_xchg_i128;
20599 return Intrinsic::ppc_atomicrmw_add_i128;
20601 return Intrinsic::ppc_atomicrmw_sub_i128;
20603 return Intrinsic::ppc_atomicrmw_and_i128;
20605 return Intrinsic::ppc_atomicrmw_or_i128;
20607 return Intrinsic::ppc_atomicrmw_xor_i128;
20609 return Intrinsic::ppc_atomicrmw_nand_i128;
20617 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20619 assert(ValTy->getPrimitiveSizeInBits() == 128);
20621 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20623 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20624 Value *LoHi = Builder.CreateIntrinsic(
20626 {AlignedAddr, IncrLo, IncrHi});
20627 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20628 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20629 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20630 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20631 return Builder.CreateOr(
20632 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20639 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20641 assert(ValTy->getPrimitiveSizeInBits() == 128);
20645 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20647 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20648 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20650 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20653 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20655 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20656 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20657 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20658 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20659 return Builder.CreateOr(
20660 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20664 return Subtarget.useCRBits();
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...
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...
@ 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 * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
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 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...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.