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_mma_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_mma_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)
12170 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12171 "Type unsupported without MMA");
12172 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12173 "Type unsupported without paired vector support");
12178 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12180 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12189 if (Subtarget.isLittleEndian()) {
12190 std::reverse(Loads.
begin(), Loads.
end());
12191 std::reverse(LoadChains.
begin(), LoadChains.
end());
12195 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12211 bool IsV1024i1 = VT == MVT::v1024i1;
12212 bool IsV2048i1 = VT == MVT::v2048i1;
12216 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12218 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12219 "Dense Math support required.");
12220 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12222 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12225 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12230 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12234 MachineSDNode *ExtNode =
12238 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12244 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12250 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12256 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12261 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12266 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12271 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12275 MachineSDNode *ExtNode =
12276 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12280 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12283 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12287 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12292 if (Subtarget.isLittleEndian())
12293 std::reverse(Values.
begin(), Values.
end());
12295 SDVTList Tys = DAG.
getVTList(MVT::Other);
12297 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12301 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12302 MachineMemOperand *NewMMO =
12309 Ops[2] = Values[Idx];
12311 MVT::v256i1, NewMMO);
12327 EVT StoreVT =
Value.getValueType();
12329 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12330 return LowerDMFVectorStore(
Op, DAG);
12332 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12338 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12339 "Type unsupported without MMA");
12340 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12341 "Type unsupported without paired vector support");
12344 unsigned NumVecs = 2;
12345 if (StoreVT == MVT::v512i1) {
12346 if (Subtarget.isISAFuture()) {
12347 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12349 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12352 Value2 =
SDValue(ExtNode, 1);
12357 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12358 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12360 if (Subtarget.isISAFuture()) {
12361 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12362 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12363 Idx > 1 ? Value2 :
Value,
12366 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12370 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12384 if (
Op.getValueType() == MVT::v4i32) {
12401 LHS,
RHS, DAG, dl, MVT::v4i32);
12404 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12409 }
else if (
Op.getValueType() == MVT::v16i8) {
12411 bool isLittleEndian = Subtarget.isLittleEndian();
12415 LHS,
RHS, DAG, dl, MVT::v8i16);
12420 LHS,
RHS, DAG, dl, MVT::v8i16);
12428 for (
unsigned i = 0; i != 8; ++i) {
12429 if (isLittleEndian) {
12431 Ops[i*2+1] = 2*i+16;
12434 Ops[i*2+1] = 2*i+1+16;
12437 if (isLittleEndian)
12447 bool IsStrict =
Op->isStrictFPOpcode();
12448 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12449 !Subtarget.hasP9Vector())
12459 "Should only be called for ISD::FP_EXTEND");
12463 if (
Op.getValueType() != MVT::v2f64 ||
12464 Op.getOperand(0).getValueType() != MVT::v2f32)
12476 "Node should have 2 operands with second one being a constant!");
12488 int DWord = Idx >> 1;
12491 if (Subtarget.isLittleEndian())
12494 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12508 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12510 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12511 LD->getMemoryVT(),
LD->getMemOperand());
12516 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
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());
12525 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12536 if (STI.useCRBits())
12553 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12554 if (STI.useCRBits())
12562 SDNode *
N =
Op.getNode();
12563 EVT VT =
N->getValueType(0);
12564 EVT CarryType =
N->getValueType(1);
12565 unsigned Opc =
N->getOpcode();
12567 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12569 N->getOperand(0),
N->getOperand(1));
12581 SDNode *
N =
Op.getNode();
12582 unsigned Opc =
N->getOpcode();
12583 EVT VT =
N->getValueType(0);
12584 EVT CarryType =
N->getValueType(1);
12585 SDValue CarryOp =
N->getOperand(2);
12587 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12593 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12607 EVT VT =
Op.getNode()->getValueType(0);
12633 EVT VT =
Op.getNode()->getValueType(0);
12662 EVT OpVT =
A.getValueType();
12663 EVT ResVT =
Op.getValueType();
12668 if (Subtarget.isPPC64() && OpVT == MVT::i32) {
12678 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12696 switch (
Op.getOpcode()) {
12716 return LowerSSUBO(
Op, DAG);
12718 return LowerSADDO(
Op, DAG);
12730 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12751 return LowerSET_ROUNDING(
Op, DAG);
12758 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12759 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12771 return LowerFP_ROUND(
Op, DAG);
12776 return LowerINTRINSIC_W_CHAIN(
Op, DAG);
12785 return LowerINTRINSIC_VOID(
Op, DAG);
12787 return LowerBSWAP(
Op, DAG);
12789 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12791 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12793 return LowerIS_FPCLASS(
Op, DAG);
12796 return LowerADDSUBO(
Op, DAG);
12799 return LowerADDSUBO_CARRY(
Op, DAG);
12801 return LowerUCMP(
Op, DAG);
12807 if (
Op->getFlags().hasNoFPExcept())
12811 return LowerVP_LOAD(
Op, DAG);
12812 case ISD::VP_STORE:
12813 return LowerVP_STORE(
Op, DAG);
12821 switch (
N->getOpcode()) {
12823 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12840 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12843 assert(
N->getValueType(0) == MVT::i1 &&
12844 "Unexpected result type for CTR decrement intrinsic");
12846 N->getValueType(0));
12856 switch (
N->getConstantOperandVal(0)) {
12857 case Intrinsic::ppc_pack_longdouble:
12859 N->getOperand(2),
N->getOperand(1)));
12861 case Intrinsic::ppc_maxfe:
12862 case Intrinsic::ppc_minfe:
12863 case Intrinsic::ppc_fnmsub:
12864 case Intrinsic::ppc_convert_f128_to_ppcf128:
12871 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12874 EVT VT =
N->getValueType(0);
12876 if (VT == MVT::i64) {
12889 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12893 Results.push_back(LoweredValue);
12894 if (
N->isStrictFPOpcode())
12899 if (!
N->getValueType(0).isVector())
12932 return Builder.CreateIntrinsic(Id, {});
12938 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12940 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12941 "Only 8/16/32/64-bit atomic loads supported");
12947 IntID = Intrinsic::ppc_lbarx;
12948 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12951 IntID = Intrinsic::ppc_lharx;
12952 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12955 IntID = Intrinsic::ppc_lwarx;
12958 IntID = Intrinsic::ppc_ldarx;
12962 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12964 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12975 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12976 "Only 8/16/32/64-bit atomic loads supported");
12982 IntID = Intrinsic::ppc_stbcx;
12983 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12986 IntID = Intrinsic::ppc_sthcx;
12987 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12990 IntID = Intrinsic::ppc_stwcx;
12993 IntID = Intrinsic::ppc_stdcx;
12997 if (SZ == 8 || SZ == 16)
12998 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13000 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13002 return Builder.CreateXor(
Call, Builder.getInt32(1));
13025 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
13035 unsigned AtomicSize,
13036 unsigned BinOpcode,
13037 unsigned CmpOpcode,
13038 unsigned CmpPred)
const {
13042 auto LoadMnemonic = PPC::LDARX;
13043 auto StoreMnemonic = PPC::STDCX;
13044 switch (AtomicSize) {
13048 LoadMnemonic = PPC::LBARX;
13049 StoreMnemonic = PPC::STBCX;
13050 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13053 LoadMnemonic = PPC::LHARX;
13054 StoreMnemonic = PPC::STHCX;
13055 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13058 LoadMnemonic = PPC::LWARX;
13059 StoreMnemonic = PPC::STWCX;
13062 LoadMnemonic = PPC::LDARX;
13063 StoreMnemonic = PPC::STDCX;
13079 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13081 F->insert(It, loopMBB);
13083 F->insert(It, loop2MBB);
13084 F->insert(It, exitMBB);
13090 Register TmpReg = (!BinOpcode) ? incr :
13091 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13092 : &PPC::GPRCRegClass);
13117 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13122 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13124 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13125 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13126 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13156 switch(
MI.getOpcode()) {
13160 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13161 &
MI.getMF()->getRegInfo());
13185 case PPC::EXTSB8_32_64:
13186 case PPC::EXTSB8_rec:
13187 case PPC::EXTSB_rec:
13190 case PPC::EXTSH8_32_64:
13191 case PPC::EXTSH8_rec:
13192 case PPC::EXTSH_rec:
13194 case PPC::EXTSWSLI:
13195 case PPC::EXTSWSLI_32_64:
13196 case PPC::EXTSWSLI_32_64_rec:
13197 case PPC::EXTSWSLI_rec:
13198 case PPC::EXTSW_32:
13199 case PPC::EXTSW_32_64:
13200 case PPC::EXTSW_32_64_rec:
13201 case PPC::EXTSW_rec:
13204 case PPC::SRAWI_rec:
13205 case PPC::SRAW_rec:
13214 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13224 bool IsSignExtended =
13227 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13228 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13229 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13230 .
addReg(
MI.getOperand(3).getReg());
13231 MI.getOperand(3).setReg(ValueReg);
13235 if (Subtarget.hasPartwordAtomics())
13243 bool is64bit = Subtarget.isPPC64();
13244 bool isLittleEndian = Subtarget.isLittleEndian();
13245 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13256 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13258 F->insert(It, loopMBB);
13260 F->insert(It, loop2MBB);
13261 F->insert(It, exitMBB);
13267 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13270 Register PtrReg = RegInfo.createVirtualRegister(RC);
13271 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13273 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13274 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13275 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13276 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13277 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13278 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13279 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13280 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13281 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13282 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13285 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13312 if (ptrA != ZeroReg) {
13313 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13314 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13322 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13323 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13326 .
addImm(is8bit ? 28 : 27);
13327 if (!isLittleEndian)
13328 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13330 .
addImm(is8bit ? 24 : 16);
13332 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13337 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13347 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13351 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13356 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13360 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13363 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13370 Register SReg = RegInfo.createVirtualRegister(GPRC);
13371 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13375 unsigned ValueReg = SReg;
13376 unsigned CmpReg = Incr2Reg;
13377 if (CmpOpcode == PPC::CMPW) {
13378 ValueReg = RegInfo.createVirtualRegister(GPRC);
13379 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13382 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13383 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13385 ValueReg = ValueSReg;
13417 .
addImm(is8bit ? 24 : 16)
13438 Register DstReg =
MI.getOperand(0).getReg();
13440 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13445 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13446 "Invalid Pointer Size!");
13495 Register BufReg =
MI.getOperand(1).getReg();
13497 if (Subtarget.is64BitELFABI()) {
13510 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13512 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13515 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13538 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13541 if (Subtarget.isPPC64()) {
13559 TII->get(PPC::PHI), DstReg)
13563 MI.eraseFromParent();
13577 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13578 "Invalid Pointer Size!");
13581 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13584 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13585 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13599 Register BufReg =
MI.getOperand(0).getReg();
13604 if (PVT == MVT::i64) {
13616 if (PVT == MVT::i64) {
13628 if (PVT == MVT::i64) {
13640 if (PVT == MVT::i64) {
13652 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13662 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13665 MI.eraseFromParent();
13681 "Unexpected stack alignment");
13685 unsigned StackProbeSize =
13688 StackProbeSize &= ~(StackAlign - 1);
13689 return StackProbeSize ? StackProbeSize : StackAlign;
13701 const bool isPPC64 = Subtarget.isPPC64();
13733 MF->
insert(MBBIter, TestMBB);
13734 MF->
insert(MBBIter, BlockMBB);
13735 MF->
insert(MBBIter, TailMBB);
13740 Register DstReg =
MI.getOperand(0).getReg();
13741 Register NegSizeReg =
MI.getOperand(1).getReg();
13753 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13759 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13760 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13762 .
addDef(ActualNegSizeReg)
13764 .
add(
MI.getOperand(2))
13765 .
add(
MI.getOperand(3));
13771 .
addReg(ActualNegSizeReg);
13774 int64_t NegProbeSize = -(int64_t)ProbeSize;
13780 .
addImm(NegProbeSize >> 16);
13784 .
addImm(NegProbeSize & 0xFFFF);
13793 .
addReg(ActualNegSizeReg)
13802 .
addReg(ActualNegSizeReg);
13812 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13839 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13840 MaxCallFrameSizeReg)
13841 .
add(
MI.getOperand(2))
13842 .
add(
MI.getOperand(3));
13843 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13845 .
addReg(MaxCallFrameSizeReg);
13851 MBB->addSuccessor(TestMBB);
13854 MI.eraseFromParent();
13856 ++NumDynamicAllocaProbed;
13861 switch (
MI.getOpcode()) {
13862 case PPC::SELECT_CC_I4:
13863 case PPC::SELECT_CC_I8:
13864 case PPC::SELECT_CC_F4:
13865 case PPC::SELECT_CC_F8:
13866 case PPC::SELECT_CC_F16:
13867 case PPC::SELECT_CC_VRRC:
13868 case PPC::SELECT_CC_VSFRC:
13869 case PPC::SELECT_CC_VSSRC:
13870 case PPC::SELECT_CC_VSRC:
13871 case PPC::SELECT_CC_SPE4:
13872 case PPC::SELECT_CC_SPE:
13880 switch (
MI.getOpcode()) {
13881 case PPC::SELECT_I4:
13882 case PPC::SELECT_I8:
13883 case PPC::SELECT_F4:
13884 case PPC::SELECT_F8:
13885 case PPC::SELECT_F16:
13886 case PPC::SELECT_SPE:
13887 case PPC::SELECT_SPE4:
13888 case PPC::SELECT_VRRC:
13889 case PPC::SELECT_VSFRC:
13890 case PPC::SELECT_VSSRC:
13891 case PPC::SELECT_VSRC:
13901 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13902 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13903 if (Subtarget.is64BitELFABI() &&
13904 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13905 !Subtarget.isUsingPCRelativeCalls()) {
13917 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13918 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13920 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13921 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13935 if (Subtarget.hasISEL() &&
13936 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13937 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13938 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13940 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13941 MI.getOpcode() == PPC::SELECT_CC_I8)
13942 Cond.push_back(
MI.getOperand(4));
13945 Cond.push_back(
MI.getOperand(1));
13948 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13949 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13965 F->insert(It, copy0MBB);
13966 F->insert(It, sinkMBB);
13975 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13990 .
addReg(
MI.getOperand(1).getReg())
13993 unsigned SelectPred =
MI.getOperand(4).getImm();
13996 .
addReg(
MI.getOperand(1).getReg())
14013 .
addReg(
MI.getOperand(3).getReg())
14015 .
addReg(
MI.getOperand(2).getReg())
14017 }
else if (
MI.getOpcode() == PPC::ReadTB) {
14033 F->insert(It, readMBB);
14034 F->insert(It, sinkMBB);
14045 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14053 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14055 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14065 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
14067 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
14069 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
14071 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
14074 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
14076 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
14078 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
14080 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
14083 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
14085 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
14087 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
14089 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14092 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14094 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14096 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14098 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14101 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14103 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14105 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14107 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14110 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14112 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14114 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14116 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14119 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14121 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14123 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14125 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14128 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14130 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14132 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14134 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14137 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14139 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14141 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14143 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14146 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14148 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14150 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14152 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14155 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14157 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14159 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14161 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14163 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14164 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14165 (Subtarget.hasPartwordAtomics() &&
14166 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14167 (Subtarget.hasPartwordAtomics() &&
14168 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14169 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14171 auto LoadMnemonic = PPC::LDARX;
14172 auto StoreMnemonic = PPC::STDCX;
14173 switch (
MI.getOpcode()) {
14176 case PPC::ATOMIC_CMP_SWAP_I8:
14177 LoadMnemonic = PPC::LBARX;
14178 StoreMnemonic = PPC::STBCX;
14179 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14181 case PPC::ATOMIC_CMP_SWAP_I16:
14182 LoadMnemonic = PPC::LHARX;
14183 StoreMnemonic = PPC::STHCX;
14184 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14186 case PPC::ATOMIC_CMP_SWAP_I32:
14187 LoadMnemonic = PPC::LWARX;
14188 StoreMnemonic = PPC::STWCX;
14190 case PPC::ATOMIC_CMP_SWAP_I64:
14191 LoadMnemonic = PPC::LDARX;
14192 StoreMnemonic = PPC::STDCX;
14199 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14200 Register oldval =
MI.getOperand(3).getReg();
14201 Register newval =
MI.getOperand(4).getReg();
14207 F->insert(It, loop1MBB);
14208 F->insert(It, loop2MBB);
14209 F->insert(It, exitMBB);
14230 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14256 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14257 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14261 bool is64bit = Subtarget.isPPC64();
14262 bool isLittleEndian = Subtarget.isLittleEndian();
14263 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14268 Register oldval =
MI.getOperand(3).getReg();
14269 Register newval =
MI.getOperand(4).getReg();
14275 F->insert(It, loop1MBB);
14276 F->insert(It, loop2MBB);
14277 F->insert(It, exitMBB);
14284 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14287 Register PtrReg = RegInfo.createVirtualRegister(RC);
14288 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14290 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14291 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14292 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14293 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14294 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14295 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14296 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14297 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14298 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14299 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14300 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14302 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14303 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14304 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14335 if (ptrA != ZeroReg) {
14336 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14337 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14346 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14347 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14350 .
addImm(is8bit ? 28 : 27);
14351 if (!isLittleEndian)
14352 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14354 .
addImm(is8bit ? 24 : 16);
14356 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14361 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14366 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14369 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14376 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14380 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14383 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14386 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14391 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14408 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14432 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14442 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14457 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14465 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14466 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14467 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14468 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14469 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14470 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14473 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14474 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14477 Register Dest = RegInfo.createVirtualRegister(
14478 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14482 .
addReg(
MI.getOperand(1).getReg())
14485 MI.getOperand(0).getReg())
14486 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14487 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14490 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14493 MI.getOperand(0).getReg())
14495 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14497 unsigned Imm =
MI.getOperand(1).getImm();
14500 MI.getOperand(0).getReg())
14502 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14504 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14508 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14510 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14521 unsigned Mode =
MI.getOperand(1).getImm();
14522 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14526 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14529 }
else if (
MI.getOpcode() == PPC::SETRND) {
14537 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14538 if (Subtarget.hasDirectMove()) {
14539 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14543 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14546 if (RC == &PPC::F8RCRegClass) {
14548 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14549 "Unsupported RegClass.");
14551 StoreOp = PPC::STFD;
14555 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14556 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14557 "Unsupported RegClass.");
14590 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14593 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14605 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14607 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14609 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14610 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14615 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14616 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14621 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14622 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14628 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14629 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14638 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14642 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14644 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14646 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14649 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14655 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14656 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14658 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14665 .
addUse(Src, {}, PPC::sub_gp8_x1);
14668 .
addUse(Src, {}, PPC::sub_gp8_x0);
14669 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14670 MI.getOpcode() == PPC::STQX_PSEUDO) {
14676 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14682 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14683 :
TII->get(PPC::STQ))
14687 }
else if (
MI.getOpcode() == PPC::LWAT_PSEUDO ||
14688 MI.getOpcode() == PPC::LDAT_PSEUDO) {
14690 Register DstReg =
MI.getOperand(0).getReg();
14691 Register PtrReg =
MI.getOperand(1).getReg();
14692 Register ValReg =
MI.getOperand(2).getReg();
14693 unsigned FC =
MI.getOperand(3).getImm();
14694 bool IsLwat =
MI.getOpcode() == PPC::LWAT_PSEUDO;
14697 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
14705 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
14708 .
addImm(PPC::sub_gp8_x0)
14710 .
addImm(PPC::sub_gp8_x1);
14713 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
14719 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14722 .
addReg(Result64, {}, PPC::sub_32);
14726 }
else if (
MI.getOpcode() == PPC::LWAT_COND_PSEUDO ||
14727 MI.getOpcode() == PPC::LDAT_COND_PSEUDO) {
14729 Register DstReg =
MI.getOperand(0).getReg();
14730 Register PtrReg =
MI.getOperand(1).getReg();
14731 unsigned FC =
MI.getOperand(2).getImm();
14732 bool IsLwat_Cond =
MI.getOpcode() == PPC::LWAT_COND_PSEUDO;
14735 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), Pair);
14738 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat_Cond ? PPC::LWAT : PPC::LDAT),
14745 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14748 .
addReg(Result64, {}, PPC::sub_32);
14756 MI.eraseFromParent();
14769 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14772 return RefinementSteps;
14779 EVT VT =
Op.getValueType();
14782 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14806PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14809 EVT VT =
Op.getValueType();
14810 if (VT != MVT::f64 &&
14811 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14814 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14818 int Enabled,
int &RefinementSteps,
14819 bool &UseOneConstNR,
14820 bool Reciprocal)
const {
14822 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14823 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14824 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14825 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14831 UseOneConstNR = !Subtarget.needsTwoConstNR();
14832 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14839 int &RefinementSteps)
const {
14841 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14842 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14843 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14844 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14847 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14863 switch (Subtarget.getCPUDirective()) {
14890 unsigned Bytes,
int Dist,
14904 if (FS != BFS || FS != (
int)Bytes)
return false;
14909 int64_t Offset1 = 0, Offset2 = 0;
14912 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14922 if (isGA1 && isGA2 && GV1 == GV2)
14923 return Offset1 == (Offset2 + Dist*Bytes);
14930 unsigned Bytes,
int Dist,
14933 EVT VT = LS->getMemoryVT();
14940 switch (
N->getConstantOperandVal(1)) {
14941 default:
return false;
14942 case Intrinsic::ppc_altivec_lvx:
14943 case Intrinsic::ppc_altivec_lvxl:
14944 case Intrinsic::ppc_vsx_lxvw4x:
14945 case Intrinsic::ppc_vsx_lxvw4x_be:
14948 case Intrinsic::ppc_vsx_lxvd2x:
14949 case Intrinsic::ppc_vsx_lxvd2x_be:
14952 case Intrinsic::ppc_altivec_lvebx:
14955 case Intrinsic::ppc_altivec_lvehx:
14958 case Intrinsic::ppc_altivec_lvewx:
14968 switch (
N->getConstantOperandVal(1)) {
14969 default:
return false;
14970 case Intrinsic::ppc_altivec_stvx:
14971 case Intrinsic::ppc_altivec_stvxl:
14972 case Intrinsic::ppc_vsx_stxvw4x:
14975 case Intrinsic::ppc_vsx_stxvd2x:
14978 case Intrinsic::ppc_vsx_stxvw4x_be:
14981 case Intrinsic::ppc_vsx_stxvd2x_be:
14984 case Intrinsic::ppc_altivec_stvebx:
14987 case Intrinsic::ppc_altivec_stvehx:
14990 case Intrinsic::ppc_altivec_stvewx:
15007 SDValue Chain = LD->getChain();
15008 EVT VT = LD->getMemoryVT();
15017 while (!Queue.empty()) {
15018 SDNode *ChainNext = Queue.pop_back_val();
15019 if (!Visited.
insert(ChainNext).second)
15026 if (!Visited.
count(ChainLD->getChain().getNode()))
15027 Queue.push_back(ChainLD->getChain().getNode());
15029 for (
const SDUse &O : ChainNext->
ops())
15030 if (!Visited.
count(O.getNode()))
15031 Queue.push_back(O.getNode());
15033 LoadRoots.
insert(ChainNext);
15044 for (
SDNode *
I : LoadRoots) {
15045 Queue.push_back(
I);
15047 while (!Queue.empty()) {
15048 SDNode *LoadRoot = Queue.pop_back_val();
15049 if (!Visited.
insert(LoadRoot).second)
15061 Queue.push_back(U);
15094 auto Final = Shifted;
15105 DAGCombinerInfo &DCI)
const {
15108 SelectionDAG &DAG = DCI.DAG;
15113 if (!DCI.isAfterLegalizeDAG())
15118 for (
const SDNode *U :
N->users())
15123 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15127 if (OpSize <
Size) {
15145 DAGCombinerInfo &DCI)
const {
15146 SelectionDAG &DAG = DCI.DAG;
15149 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15160 N->getValueType(0) != MVT::i1)
15163 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15164 N->getOperand(0).getValueType() != MVT::i64)
15174 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15185 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15208 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15209 N->getOperand(0).getOpcode() !=
ISD::OR &&
15210 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15220 N->getOperand(1).getOpcode() !=
ISD::AND &&
15221 N->getOperand(1).getOpcode() !=
ISD::OR &&
15222 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15233 SmallPtrSet<SDNode *, 16> Visited;
15235 for (
unsigned i = 0; i < 2; ++i) {
15239 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15251 while (!BinOps.
empty()) {
15259 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15293 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15297 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15298 if (User !=
N && !Visited.
count(User))
15307 if (
User->getOperand(0) == Inputs[i])
15310 if (
User->getOperand(0) == Inputs[i] ||
15311 User->getOperand(1) == Inputs[i])
15317 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15318 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15319 if (User !=
N && !Visited.
count(User))
15328 if (
User->getOperand(0) == PromOps[i])
15331 if (
User->getOperand(0) == PromOps[i] ||
15332 User->getOperand(1) == PromOps[i])
15339 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15348 std::list<HandleSDNode> PromOpHandles;
15349 for (
auto &PromOp : PromOps)
15350 PromOpHandles.emplace_back(PromOp);
15357 while (!PromOpHandles.empty()) {
15358 SDValue PromOp = PromOpHandles.back().getValue();
15359 PromOpHandles.pop_back();
15368 PromOpHandles.emplace_front(PromOp);
15382 default:
C = 0;
break;
15395 PromOpHandles.emplace_front(PromOp);
15402 for (
unsigned i = 0; i < 2; ++i)
15412 return N->getOperand(0);
15420 DAGCombinerInfo &DCI)
const {
15421 SelectionDAG &DAG = DCI.DAG;
15438 if (
N->getValueType(0) != MVT::i32 &&
15439 N->getValueType(0) != MVT::i64)
15442 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15443 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15446 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15447 N->getOperand(0).getOpcode() !=
ISD::OR &&
15448 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15455 SmallPtrSet<SDNode *, 16> Visited;
15459 while (!BinOps.
empty()) {
15467 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15493 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15498 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15503 if (User !=
N && !Visited.
count(User))
15509 if (
User->getOperand(0) == Inputs[i])
15510 SelectTruncOp[0].
insert(std::make_pair(User,
15511 User->getOperand(0).getValueType()));
15513 if (
User->getOperand(0) == Inputs[i])
15514 SelectTruncOp[0].
insert(std::make_pair(User,
15515 User->getOperand(0).getValueType()));
15516 if (
User->getOperand(1) == Inputs[i])
15517 SelectTruncOp[1].
insert(std::make_pair(User,
15518 User->getOperand(1).getValueType()));
15523 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15525 if (User !=
N && !Visited.
count(User))
15531 if (
User->getOperand(0) == PromOps[i])
15532 SelectTruncOp[0].
insert(std::make_pair(User,
15533 User->getOperand(0).getValueType()));
15535 if (
User->getOperand(0) == PromOps[i])
15536 SelectTruncOp[0].
insert(std::make_pair(User,
15537 User->getOperand(0).getValueType()));
15538 if (
User->getOperand(1) == PromOps[i])
15539 SelectTruncOp[1].
insert(std::make_pair(User,
15540 User->getOperand(1).getValueType()));
15545 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15546 bool ReallyNeedsExt =
false;
15550 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15555 Inputs[i].getOperand(0).getValueSizeInBits();
15556 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15561 OpBits-PromBits))) ||
15564 (OpBits-(PromBits-1)))) {
15565 ReallyNeedsExt =
true;
15573 std::list<HandleSDNode> PromOpHandles;
15574 for (
auto &PromOp : PromOps)
15575 PromOpHandles.emplace_back(PromOp);
15579 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15586 SDValue InSrc = Inputs[i].getOperand(0);
15604 while (!PromOpHandles.empty()) {
15606 PromOpHandles.pop_back();
15610 default:
C = 0;
break;
15623 PromOpHandles.emplace_front(PromOp);
15633 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15635 PromOpHandles.emplace_front(PromOp);
15643 for (
unsigned i = 0; i < 2; ++i) {
15661 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15662 if (SI0 != SelectTruncOp[0].
end())
15664 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15665 if (SI1 != SelectTruncOp[1].
end())
15674 if (!ReallyNeedsExt)
15675 return N->getOperand(0);
15682 N->getValueSizeInBits(0), PromBits),
15683 dl,
N->getValueType(0)));
15686 "Invalid extension type");
15689 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15699 auto isValidForConvert = [](
SDValue &Operand) {
15718 if (LoadNode->isVolatile())
15739 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15749 "CC mus be ISD::SETNE or ISD::SETEQ");
15751 auto getV16i8Load = [&](
const SDValue &Operand) {
15758 return DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15759 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15798 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15799 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15802 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15805 IntrID, CRSel, LHSVec, RHSVec);
15808 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15826 auto IsAndWithOne = [](
SDValue &V) {
15837 auto IsCompareWithZero = [](
SDValue &V) {
15844 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15845 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15862 auto MakeXor1 = [&](
SDValue V) {
15863 EVT VT = V.getValueType();
15870 return MakeXor1(
LHS);
15873 return MakeXor1(
RHS);
15879 DAGCombinerInfo &DCI)
const {
15881 "Should be called with a SETCC node");
15903 SelectionDAG &DAG = DCI.DAG;
15904 EVT VT =
N->getValueType(0);
15905 EVT OpVT =
LHS.getValueType();
15927 return DAGCombineTruncBoolExt(
N, DCI);
15934 Op.getValueType() == MVT::f64;
15946combineElementTruncationToVectorTruncation(
SDNode *
N,
15947 DAGCombinerInfo &DCI)
const {
15949 "Should be called with a BUILD_VECTOR node");
15951 SelectionDAG &DAG = DCI.DAG;
15954 SDValue FirstInput =
N->getOperand(0);
15956 "The input operand must be an fp-to-int conversion.");
15961 if (FirstConversion == PPCISD::FCTIDZ ||
15962 FirstConversion == PPCISD::FCTIDUZ ||
15963 FirstConversion == PPCISD::FCTIWZ ||
15964 FirstConversion == PPCISD::FCTIWUZ) {
15965 bool IsSplat =
true;
15966 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
15967 FirstConversion == PPCISD::FCTIWUZ;
15970 EVT TargetVT =
N->getValueType(0);
15971 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15972 SDValue NextOp =
N->getOperand(i);
15973 if (NextOp.
getOpcode() != PPCISD::MFVSR)
15976 if (NextConversion != FirstConversion)
15984 if (
N->getOperand(i) != FirstInput)
15995 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15996 SDValue In =
N->getOperand(i).getOperand(0);
16006 Ops.push_back(Trunc);
16009 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16013 if (FirstConversion == PPCISD::FCTIDZ ||
16014 FirstConversion == PPCISD::FCTIWZ)
16019 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16021 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16039 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16043 if (FullVal == BasePattern)
16044 return std::make_tuple(Uim,
uint8_t{0});
16047 if (FullVal ==
APInt(128, 1))
16048 return std::make_tuple(Uim,
uint8_t{127});
16050 return std::nullopt;
16070 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16074 EVT VT =
Op.getValueType();
16075 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16089 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16099 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16103 uint64_t ElemValue =
C->getZExtValue();
16107 ElemValue &= ((1ULL << ElemBits) - 1);
16111 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16114 APInt ElemAPInt(128, ElemValue);
16115 ElemAPInt <<= BitPos;
16118 FullVal |= ElemAPInt;
16125 const auto &[Uim, ShiftAmount] = *UIMOpt;
16129 if (ShiftAmount == 0) {
16134 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16135 LxvkqInstr.
dump());
16139 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16151 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16154 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16170 "Should be called with a BUILD_VECTOR node");
16175 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16178 bool InputsAreConsecutiveLoads =
true;
16179 bool InputsAreReverseConsecutive =
true;
16180 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16181 SDValue FirstInput =
N->getOperand(0);
16182 bool IsRoundOfExtLoad =
false;
16192 N->getNumOperands() == 1)
16195 if (!IsRoundOfExtLoad)
16200 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16202 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16205 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16211 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16222 InputsAreConsecutiveLoads =
false;
16224 InputsAreReverseConsecutive =
false;
16227 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16232 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16233 "The loads cannot be both consecutive and reverse consecutive.");
16237 if (InputsAreConsecutiveLoads) {
16238 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16242 ReturnSDVal = WideLoad;
16243 }
else if (InputsAreReverseConsecutive) {
16245 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16250 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16258 for (
auto *LD : InputLoads)
16260 return ReturnSDVal;
16271 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16277 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16279 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16281 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16282 CorrectElems = CorrectElems >> 8;
16283 Elems = Elems >> 8;
16290 EVT VT =
N->getValueType(0);
16294 Input.getValueType().getVectorElementType(),
16328 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16354 Elems = Elems << 8;
16363 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16364 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16371 int TgtElemArrayIdx;
16372 int InputSize =
Input.getValueType().getScalarSizeInBits();
16373 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16374 if (InputSize + OutputSize == 40)
16375 TgtElemArrayIdx = 0;
16376 else if (InputSize + OutputSize == 72)
16377 TgtElemArrayIdx = 1;
16378 else if (InputSize + OutputSize == 48)
16379 TgtElemArrayIdx = 2;
16380 else if (InputSize + OutputSize == 80)
16381 TgtElemArrayIdx = 3;
16382 else if (InputSize + OutputSize == 96)
16383 TgtElemArrayIdx = 4;
16387 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16389 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16390 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16391 if (Elems != CorrectElems) {
16407 if (
N->getValueType(0) != MVT::v1i128)
16410 SDValue Operand =
N->getOperand(0);
16417 EVT MemoryType = LD->getMemoryVT();
16421 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16422 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16425 if (!ValidLDType ||
16431 LD->getChain(), LD->getBasePtr(),
16435 DAG.
getVTList(MVT::v1i128, MVT::Other),
16436 LoadOps, MemoryType, LD->getMemOperand());
16440 DAGCombinerInfo &DCI)
const {
16442 "Should be called with a BUILD_VECTOR node");
16444 SelectionDAG &DAG = DCI.DAG;
16447 if (!Subtarget.hasVSX())
16454 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16455 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16470 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16479 if (Subtarget.isISA3_1()) {
16485 if (
N->getValueType(0) != MVT::v2f64)
16496 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16507 if (!Ext1Op || !Ext2Op)
16516 if (FirstElem == 0 && SecondElem == 1)
16517 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16518 else if (FirstElem == 2 && SecondElem == 3)
16519 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16525 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16526 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16531 DAGCombinerInfo &DCI)
const {
16534 "Need an int -> FP conversion node here");
16539 SelectionDAG &DAG = DCI.DAG;
16545 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16547 if (!
Op.getOperand(0).getValueType().isSimple())
16549 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16550 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16553 SDValue FirstOperand(
Op.getOperand(0));
16554 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16555 (FirstOperand.getValueType() == MVT::i8 ||
16556 FirstOperand.getValueType() == MVT::i16);
16557 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16559 bool DstDouble =
Op.getValueType() == MVT::f64;
16560 unsigned ConvOp =
Signed ?
16561 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16562 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16567 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16570 Ops, MVT::i8, LDN->getMemOperand());
16575 SDValue ExtOps[] = { Ld, WidthConst };
16577 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16579 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16587 if (
Op.getOperand(0).getValueType() == MVT::i32)
16591 "UINT_TO_FP is supported only with FPCVT");
16595 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16600 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16607 Subtarget.hasFPCVT()) ||
16609 SDValue Src =
Op.getOperand(0).getOperand(0);
16610 if (Src.getValueType() == MVT::f32) {
16612 DCI.AddToWorklist(Src.getNode());
16613 }
else if (Src.getValueType() != MVT::f64) {
16625 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16628 DCI.AddToWorklist(
FP.getNode());
16652 switch (
N->getOpcode()) {
16657 Chain = LD->getChain();
16658 Base = LD->getBasePtr();
16659 MMO = LD->getMemOperand();
16678 MVT VecTy =
N->getValueType(0).getSimpleVT();
16686 Chain = Load.getValue(1);
16688 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16692 if (VecTy != MVT::v2f64) {
16719 switch (
N->getOpcode()) {
16724 Chain = ST->getChain();
16725 Base = ST->getBasePtr();
16726 MMO = ST->getMemOperand();
16746 SDValue Src =
N->getOperand(SrcOpnd);
16747 MVT VecTy = Src.getValueType().getSimpleVT();
16750 if (VecTy != MVT::v2f64) {
16756 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16762 StoreOps, VecTy, MMO);
16769 DAGCombinerInfo &DCI)
const {
16772 unsigned Opcode =
N->getOperand(1).getOpcode();
16774 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16778 &&
"Not a FP_TO_INT Instruction!");
16780 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16781 EVT Op1VT =
N->getOperand(1).getValueType();
16784 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16788 bool ValidTypeForStoreFltAsInt =
16789 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16790 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16793 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16796 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16804 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16819 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16820 for (
int i = 1, e = Mask.size(); i < e; i++) {
16821 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16823 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16825 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16836 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16837 FirstOp =
Op.getOperand(i);
16843 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16844 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16854 Op =
Op.getOperand(0);
16870 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16871 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16873 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16875 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16876 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16877 int Idx = ShuffV[
I];
16878 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16879 ShuffV[
I] += LHSEltFixup;
16880 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16881 ShuffV[
I] += RHSEltFixup;
16892 SDLoc dl(OrigSToV);
16895 "Expecting a SCALAR_TO_VECTOR here");
16908 "Cannot produce a permuted scalar_to_vector for one element vector");
16910 unsigned ResultInElt = NumElts / 2;
16916 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
16921 int HalfVec,
int LHSLastElementDefined,
16922 int RHSLastElementDefined) {
16923 for (
int Index : ShuffV) {
16927 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16928 (Index > LHSLastElementDefined))
16931 if ((RHSLastElementDefined >= 0) &&
16932 (Index > HalfVec + RHSLastElementDefined))
16939 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16940 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16956 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16957 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16960 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16961 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16962 return SToVPermuted;
16982 int NumElts =
LHS.getValueType().getVectorNumElements();
16985 bool IsLittleEndian = Subtarget.isLittleEndian();
16992 if (!Subtarget.hasDirectMove())
17012 SmallVector<int, 16> ShuffV(Mask);
17015 if (SToVLHS || SToVRHS) {
17018 int ShuffleNumElts = ShuffV.
size();
17019 int HalfVec = ShuffleNumElts / 2;
17025 unsigned LHSNumValidElts = HalfVec;
17026 unsigned RHSNumValidElts = HalfVec;
17031 int LHSFirstElt = 0;
17032 int RHSFirstElt = ShuffleNumElts;
17033 int LHSLastElt = -1;
17034 int RHSLastElt = -1;
17042 int LHSScalarSize = 0;
17043 int RHSScalarSize = 0;
17046 if (!IsLittleEndian && LHSScalarSize >= 64)
17051 if (!IsLittleEndian && RHSScalarSize >= 64)
17054 if (LHSScalarSize != 0)
17056 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17057 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17058 if (RHSScalarSize != 0)
17060 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17061 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17072 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17073 LHSNumValidElts, RHSNumValidElts, Subtarget);
17099 if (IsLittleEndian) {
17102 if (Mask[0] < NumElts)
17103 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17107 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17112 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17116 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17121 if (Mask[0] < NumElts)
17122 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17126 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17131 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17135 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17145 if (IsLittleEndian)
17154 DAGCombinerInfo &DCI)
const {
17156 "Not a reverse memop pattern!");
17158 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17161 auto I =
Mask.rbegin();
17162 auto E =
Mask.rend();
17164 for (;
I !=
E; ++
I) {
17172 SelectionDAG &DAG = DCI.DAG;
17175 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17181 if (!Subtarget.hasP9Vector())
17184 if(!IsElementReverse(SVN))
17191 for (SDUse &Use : LSBase->
uses())
17192 if (
Use.getResNo() == 0 &&
17199 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17214 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17223 if (IntrinsicID == Intrinsic::ppc_stdcx)
17225 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17227 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17229 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17238 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17242 if (
LHS->getOpcode() == PPCISD::ADDE &&
17294 auto isZeroOrOne = [=](
SDValue &V) {
17296 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17301 if (!isZeroOrOne(NonNullConstant))
17311 EVT VType =
N->getValueType(0);
17315 return NewNonNullConstant;
17334 EVT XorVT =
N->getValueType(0);
17335 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17343 if (!XorConst || !XorConst->
isOne()) {
17345 if (!XorConst || !XorConst->
isOne())
17352 if (!
LHS.hasOneUse())
17360 SelectNode =
LHS.getOperand(0);
17374 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17384 if (!ConstOp1 || !ConstOp2)
17388 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17397 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17399 bool ConstOp1IsOne = ConstOp1->
isOne();
17402 {SelectNode.getOperand(0),
17403 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17404 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17405 SelectNode.getOperand(3)}),
17413 switch (
N->getOpcode()) {
17416 return combineADD(
N, DCI);
17448 return combineSHL(
N, DCI);
17450 return combineSRA(
N, DCI);
17452 return combineSRL(
N, DCI);
17454 return combineMUL(
N, DCI);
17456 case PPCISD::FNMSUB:
17457 return combineFMALike(
N, DCI);
17460 return N->getOperand(0);
17464 return N->getOperand(0);
17470 return N->getOperand(0);
17479 return DAGCombineExtBoolTrunc(
N, DCI);
17481 return combineTRUNCATE(
N, DCI);
17483 if (
SDValue CSCC = combineSetCC(
N, DCI))
17487 return DAGCombineTruncBoolExt(
N, DCI);
17490 return combineFPToIntToFP(
N, DCI);
17499 EVT Op1VT =
N->getOperand(1).getValueType();
17500 unsigned Opcode =
N->getOperand(1).getOpcode();
17504 SDValue Val = combineStoreFPToInt(
N, DCI);
17518 N->getOperand(1).getNode()->hasOneUse() &&
17519 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17520 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17528 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17535 if (Op1VT.
bitsGT(mVT)) {
17540 if (Op1VT == MVT::i64)
17545 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17565 ST->getBasePtr(), ST->getOffset(), MemVT,
17566 ST->getMemOperand(), ST->getAddressingMode(),
17570 return ST->isUnindexed()
17579 if (Subtarget.needsSwapsForVSXMemOps() &&
17580 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17581 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17588 EVT VT = LD->getValueType(0);
17594 if (Subtarget.needsSwapsForVSXMemOps() &&
17595 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17596 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17607 auto ReplaceTwoFloatLoad = [&]() {
17608 if (VT != MVT::i64)
17623 if (!LD->hasNUsesOfValue(2, 0))
17626 auto UI = LD->user_begin();
17627 while (UI.getUse().getResNo() != 0) ++UI;
17629 while (UI.getUse().getResNo() != 0) ++UI;
17630 SDNode *RightShift = *UI;
17638 if (RightShift->getOpcode() !=
ISD::SRL ||
17640 RightShift->getConstantOperandVal(1) != 32 ||
17641 !RightShift->hasOneUse())
17644 SDNode *Trunc2 = *RightShift->user_begin();
17654 Bitcast->getValueType(0) != MVT::f32)
17660 if (Subtarget.isLittleEndian())
17666 SDValue BasePtr = LD->getBasePtr();
17667 if (LD->isIndexed()) {
17669 "Non-pre-inc AM on PPC?");
17677 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17678 LD->getPointerInfo(), LD->getAlign(),
17679 MMOFlags, LD->getAAInfo());
17685 LD->getPointerInfo().getWithOffset(4),
17688 if (LD->isIndexed()) {
17702 if (ReplaceTwoFloatLoad())
17705 EVT MemVT = LD->getMemoryVT();
17708 if (LD->isUnindexed() && VT.
isVector() &&
17711 !Subtarget.hasP8Vector() &&
17712 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17713 VT == MVT::v4f32))) &&
17714 LD->getAlign() < ABIAlignment) {
17716 SDValue Chain = LD->getChain();
17717 SDValue Ptr = LD->getBasePtr();
17718 bool isLittleEndian = Subtarget.isLittleEndian();
17745 MVT PermCntlTy, PermTy, LDTy;
17746 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17747 : Intrinsic::ppc_altivec_lvsl;
17748 IntrLD = Intrinsic::ppc_altivec_lvx;
17749 IntrPerm = Intrinsic::ppc_altivec_vperm;
17750 PermCntlTy = MVT::v16i8;
17751 PermTy = MVT::v4i32;
17770 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
17774 BaseLoadOps, LDTy, BaseMMO);
17783 int IncValue = IncOffset;
17800 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
17804 ExtraLoadOps, LDTy, ExtraMMO);
17815 if (isLittleEndian)
17817 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17820 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17823 Perm = Subtarget.hasAltivec()
17838 bool isLittleEndian = Subtarget.isLittleEndian();
17839 unsigned IID =
N->getConstantOperandVal(0);
17840 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17841 : Intrinsic::ppc_altivec_lvsl);
17842 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17849 .zext(
Add.getScalarValueSizeInBits()))) {
17850 SDNode *BasePtr =
Add->getOperand(0).getNode();
17851 for (
SDNode *U : BasePtr->users()) {
17853 U->getConstantOperandVal(0) == IID) {
17864 SDNode *BasePtr =
Add->getOperand(0).getNode();
17865 for (
SDNode *U : BasePtr->users()) {
17868 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17874 V->getConstantOperandVal(0) == IID) {
17886 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17887 IID == Intrinsic::ppc_altivec_vmaxsh ||
17888 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17919 switch (
N->getConstantOperandVal(1)) {
17922 case Intrinsic::ppc_altivec_vsum4sbs:
17923 case Intrinsic::ppc_altivec_vsum4shs:
17924 case Intrinsic::ppc_altivec_vsum4ubs: {
17931 APInt APSplatBits, APSplatUndef;
17932 unsigned SplatBitSize;
17935 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17936 !Subtarget.isLittleEndian());
17938 if (BVNIsConstantSplat && APSplatBits == 0)
17943 case Intrinsic::ppc_vsx_lxvw4x:
17944 case Intrinsic::ppc_vsx_lxvd2x:
17947 if (Subtarget.needsSwapsForVSXMemOps())
17955 if (Subtarget.needsSwapsForVSXMemOps()) {
17956 switch (
N->getConstantOperandVal(1)) {
17959 case Intrinsic::ppc_vsx_stxvw4x:
17960 case Intrinsic::ppc_vsx_stxvd2x:
17969 bool Is64BitBswapOn64BitTgt =
17970 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17972 N->getOperand(0).hasOneUse();
17973 if (IsSingleUseNormalLd &&
17974 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17975 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17986 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17987 MVT::i64 : MVT::i32, MVT::Other),
17988 Ops, LD->getMemoryVT(), LD->getMemOperand());
17992 if (
N->getValueType(0) == MVT::i16)
18009 !IsSingleUseNormalLd)
18014 if (!LD->isSimple())
18016 SDValue BasePtr = LD->getBasePtr();
18018 LD->getPointerInfo(), LD->getAlign());
18023 LD->getMemOperand(), 4, 4);
18027 if (Subtarget.isLittleEndian())
18033 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18042 if (!
N->getOperand(0).hasOneUse() &&
18043 !
N->getOperand(1).hasOneUse() &&
18044 !
N->getOperand(2).hasOneUse()) {
18047 SDNode *VCMPrecNode =
nullptr;
18049 SDNode *LHSN =
N->getOperand(0).getNode();
18051 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18055 VCMPrecNode =
User;
18067 SDNode *FlagUser =
nullptr;
18069 FlagUser ==
nullptr; ++UI) {
18070 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18083 return SDValue(VCMPrecNode, 0);
18094 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18105 auto RHSAPInt = RHS->getAsAPIntVal();
18106 if (!RHSAPInt.isIntN(64))
18109 unsigned Val = RHSAPInt.getZExtValue();
18110 auto isImpossibleCompare = [&]() {
18113 if (Val != 0 && Val != 1) {
18115 return N->getOperand(0);
18118 N->getOperand(0),
N->getOperand(4));
18123 unsigned StoreWidth = 0;
18126 if (
SDValue Impossible = isImpossibleCompare())
18138 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18142 PPCISD::STORE_COND, dl,
18144 MemNode->getMemoryVT(), MemNode->getMemOperand());
18148 if (
N->getOperand(0) == LHS.getValue(1))
18159 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18161 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18167 assert(isDot &&
"Can't compare against a vector result!");
18169 if (
SDValue Impossible = isImpossibleCompare())
18172 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18179 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18184 switch (LHS.getConstantOperandVal(1)) {
18200 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18203 N->getOperand(4), CompNode.
getValue(1));
18208 return DAGCombineBuildVector(
N, DCI);
18221 EVT VT =
N->getValueType(0);
18222 if (VT == MVT::i64 && !Subtarget.isPPC64())
18224 if ((VT != MVT::i32 && VT != MVT::i64) ||
18232 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18252 const APInt &DemandedElts,
18254 unsigned Depth)
const {
18256 switch (
Op.getOpcode()) {
18258 case PPCISD::LBRX: {
18261 Known.
Zero = 0xFFFF0000;
18264 case PPCISD::ADDE: {
18265 if (
Op.getResNo() == 0) {
18270 Known.
Zero = ~1ULL;
18275 switch (
Op.getConstantOperandVal(0)) {
18277 case Intrinsic::ppc_altivec_vcmpbfp_p:
18278 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18279 case Intrinsic::ppc_altivec_vcmpequb_p:
18280 case Intrinsic::ppc_altivec_vcmpequh_p:
18281 case Intrinsic::ppc_altivec_vcmpequw_p:
18282 case Intrinsic::ppc_altivec_vcmpequd_p:
18283 case Intrinsic::ppc_altivec_vcmpequq_p:
18284 case Intrinsic::ppc_altivec_vcmpgefp_p:
18285 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18286 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18287 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18288 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18289 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18290 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18291 case Intrinsic::ppc_altivec_vcmpgtub_p:
18292 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18293 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18294 case Intrinsic::ppc_altivec_vcmpgtud_p:
18295 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18302 switch (
Op.getConstantOperandVal(1)) {
18305 case Intrinsic::ppc_load2r:
18307 Known.
Zero = 0xFFFF0000;
18316 switch (Subtarget.getCPUDirective()) {
18338 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18347 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18349 LoopSize +=
TII->getInstSizeInBytes(J);
18354 if (LoopSize > 16 && LoopSize <= 32)
18368 if (Constraint.
size() == 1) {
18369 switch (Constraint[0]) {
18387 }
else if (Constraint ==
"wc") {
18389 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18390 Constraint ==
"wf" || Constraint ==
"ws" ||
18391 Constraint ==
"wi" || Constraint ==
"ww") {
18404 Value *CallOperandVal =
info.CallOperandVal;
18407 if (!CallOperandVal)
18414 else if ((
StringRef(constraint) ==
"wa" ||
18426 switch (*constraint) {
18456std::pair<unsigned, const TargetRegisterClass *>
18460 if (Constraint.
size() == 1) {
18462 switch (Constraint[0]) {
18464 if (VT == MVT::i64 && Subtarget.isPPC64())
18465 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18466 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18468 if (VT == MVT::i64 && Subtarget.isPPC64())
18469 return std::make_pair(0U, &PPC::G8RCRegClass);
18470 return std::make_pair(0U, &PPC::GPRCRegClass);
18476 if (Subtarget.hasSPE()) {
18477 if (VT == MVT::f32 || VT == MVT::i32)
18478 return std::make_pair(0U, &PPC::GPRCRegClass);
18479 if (VT == MVT::f64 || VT == MVT::i64)
18480 return std::make_pair(0U, &PPC::SPERCRegClass);
18482 if (VT == MVT::f32 || VT == MVT::i32)
18483 return std::make_pair(0U, &PPC::F4RCRegClass);
18484 if (VT == MVT::f64 || VT == MVT::i64)
18485 return std::make_pair(0U, &PPC::F8RCRegClass);
18489 if (Subtarget.hasAltivec() && VT.
isVector())
18490 return std::make_pair(0U, &PPC::VRRCRegClass);
18491 else if (Subtarget.hasVSX())
18493 return std::make_pair(0U, &PPC::VFRCRegClass);
18496 return std::make_pair(0U, &PPC::CRRCRegClass);
18498 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18500 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18501 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18502 Constraint ==
"wf" || Constraint ==
"wi") &&
18503 Subtarget.hasVSX()) {
18507 return std::make_pair(0U, &PPC::VSRCRegClass);
18508 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18509 return std::make_pair(0U, &PPC::VSSRCRegClass);
18510 return std::make_pair(0U, &PPC::VSFRCRegClass);
18511 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18512 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18513 return std::make_pair(0U, &PPC::VSSRCRegClass);
18515 return std::make_pair(0U, &PPC::VSFRCRegClass);
18516 }
else if (Constraint ==
"lr") {
18517 if (VT == MVT::i64)
18518 return std::make_pair(0U, &PPC::LR8RCRegClass);
18520 return std::make_pair(0U, &PPC::LRRCRegClass);
18525 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18529 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18530 int VSNum = atoi(Constraint.
data() + 3);
18531 assert(VSNum >= 0 && VSNum <= 63 &&
18532 "Attempted to access a vsr out of range");
18534 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18535 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18540 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18541 int RegNum = atoi(Constraint.
data() + 2);
18542 if (RegNum > 31 || RegNum < 0)
18544 if (VT == MVT::f32 || VT == MVT::i32)
18545 return Subtarget.hasSPE()
18546 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18547 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18548 if (VT == MVT::f64 || VT == MVT::i64)
18549 return Subtarget.hasSPE()
18550 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18551 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18555 std::pair<unsigned, const TargetRegisterClass *> R =
18564 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18565 PPC::GPRCRegClass.contains(R.first))
18566 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18567 PPC::sub_32, &PPC::G8RCRegClass),
18568 &PPC::G8RCRegClass);
18571 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18572 R.first = PPC::CR0;
18573 R.second = &PPC::CRRCRegClass;
18577 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18578 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18579 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18580 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18581 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18582 "default AIX AltiVec ABI and cannot be used\n";
18592 std::vector<SDValue> &
Ops,
18597 if (Constraint.
size() > 1)
18600 char Letter = Constraint[0];
18615 EVT TCVT = MVT::i64;
18656 if (Result.getNode()) {
18657 Ops.push_back(Result);
18668 if (
I.getNumOperands() <= 1)
18672 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18673 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18674 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18677 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18693 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18705 switch (AM.
Scale) {
18733 unsigned Depth =
Op.getConstantOperandVal(0);
18757 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18765 unsigned Depth =
Op.getConstantOperandVal(0);
18772 bool isPPC64 = PtrVT == MVT::i64;
18778 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18780 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18786 FrameAddr, MachinePointerInfo());
18790#define GET_REGISTER_MATCHER
18791#include "PPCGenAsmMatcher.inc"
18795 bool IsPPC64 = Subtarget.isPPC64();
18807 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18813 Reg = Reg.id() - PPC::R0 + PPC::X0;
18820 if (Subtarget.is32BitELFABI())
18825 if (Subtarget.isAIXABI())
18839 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18855 case Intrinsic::ppc_atomicrmw_xchg_i128:
18856 case Intrinsic::ppc_atomicrmw_add_i128:
18857 case Intrinsic::ppc_atomicrmw_sub_i128:
18858 case Intrinsic::ppc_atomicrmw_nand_i128:
18859 case Intrinsic::ppc_atomicrmw_and_i128:
18860 case Intrinsic::ppc_atomicrmw_or_i128:
18861 case Intrinsic::ppc_atomicrmw_xor_i128:
18862 case Intrinsic::ppc_cmpxchg_i128:
18864 Info.memVT = MVT::i128;
18865 Info.ptrVal =
I.getArgOperand(0);
18867 Info.align =
Align(16);
18872 case Intrinsic::ppc_atomic_load_i128:
18874 Info.memVT = MVT::i128;
18875 Info.ptrVal =
I.getArgOperand(0);
18877 Info.align =
Align(16);
18881 case Intrinsic::ppc_atomic_store_i128:
18883 Info.memVT = MVT::i128;
18884 Info.ptrVal =
I.getArgOperand(2);
18886 Info.align =
Align(16);
18890 case Intrinsic::ppc_altivec_lvx:
18891 case Intrinsic::ppc_altivec_lvxl:
18892 case Intrinsic::ppc_altivec_lvebx:
18893 case Intrinsic::ppc_altivec_lvehx:
18894 case Intrinsic::ppc_altivec_lvewx:
18895 case Intrinsic::ppc_vsx_lxvd2x:
18896 case Intrinsic::ppc_vsx_lxvw4x:
18897 case Intrinsic::ppc_vsx_lxvd2x_be:
18898 case Intrinsic::ppc_vsx_lxvw4x_be:
18899 case Intrinsic::ppc_vsx_lxvl:
18900 case Intrinsic::ppc_vsx_lxvll: {
18903 case Intrinsic::ppc_altivec_lvebx:
18906 case Intrinsic::ppc_altivec_lvehx:
18909 case Intrinsic::ppc_altivec_lvewx:
18912 case Intrinsic::ppc_vsx_lxvd2x:
18913 case Intrinsic::ppc_vsx_lxvd2x_be:
18923 Info.ptrVal =
I.getArgOperand(0);
18926 Info.align =
Align(1);
18931 case Intrinsic::ppc_altivec_stvx:
18932 case Intrinsic::ppc_altivec_stvxl:
18933 case Intrinsic::ppc_altivec_stvebx:
18934 case Intrinsic::ppc_altivec_stvehx:
18935 case Intrinsic::ppc_altivec_stvewx:
18936 case Intrinsic::ppc_vsx_stxvd2x:
18937 case Intrinsic::ppc_vsx_stxvw4x:
18938 case Intrinsic::ppc_vsx_stxvd2x_be:
18939 case Intrinsic::ppc_vsx_stxvw4x_be:
18940 case Intrinsic::ppc_vsx_stxvl:
18941 case Intrinsic::ppc_vsx_stxvll: {
18944 case Intrinsic::ppc_altivec_stvebx:
18947 case Intrinsic::ppc_altivec_stvehx:
18950 case Intrinsic::ppc_altivec_stvewx:
18953 case Intrinsic::ppc_vsx_stxvd2x:
18954 case Intrinsic::ppc_vsx_stxvd2x_be:
18964 Info.ptrVal =
I.getArgOperand(1);
18967 Info.align =
Align(1);
18972 case Intrinsic::ppc_stdcx:
18973 case Intrinsic::ppc_stwcx:
18974 case Intrinsic::ppc_sthcx:
18975 case Intrinsic::ppc_stbcx: {
18977 auto Alignment =
Align(8);
18979 case Intrinsic::ppc_stdcx:
18982 case Intrinsic::ppc_stwcx:
18984 Alignment =
Align(4);
18986 case Intrinsic::ppc_sthcx:
18988 Alignment =
Align(2);
18990 case Intrinsic::ppc_stbcx:
18992 Alignment =
Align(1);
18997 Info.ptrVal =
I.getArgOperand(0);
18999 Info.align = Alignment;
19013 const AttributeList &FuncAttributes)
const {
19017 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19018 if (
Op.isMemset() && Subtarget.hasVSX()) {
19023 if (TailSize > 2 && TailSize <= 4) {
19028 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19033 if (Subtarget.isPPC64()) {
19044 assert(Ty->isIntegerTy());
19046 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19047 return !(BitSize == 0 || BitSize > 64);
19055 return NumBits1 == 64 && NumBits2 == 32;
19063 return NumBits1 == 64 && NumBits2 == 32;
19070 EVT MemVT = LD->getMemoryVT();
19071 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19072 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19088 "invalid fpext types");
19090 if (DestVT == MVT::f128)
19105 unsigned *
Fast)
const {
19119 !Subtarget.allowsUnalignedFPAccess())
19123 if (Subtarget.hasVSX()) {
19124 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19125 VT != MVT::v4f32 && VT != MVT::v4i32)
19132 if (VT == MVT::ppcf128)
19147 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19155 int64_t Imm = ConstNode->getSExtValue();
19176 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19178 switch (Ty->getScalarType()->getTypeID()) {
19183 return Subtarget.hasP9Vector();
19191 if (!
I->hasOneUse())
19195 assert(
User &&
"A single use instruction with no uses.");
19197 switch (
I->getOpcode()) {
19198 case Instruction::FMul: {
19200 if (
User->getOpcode() != Instruction::FSub &&
19201 User->getOpcode() != Instruction::FAdd)
19208 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19209 User->getFastMathFlags().allowContract();
19215 case Instruction::Load: {
19228 if (
User->getOpcode() != Instruction::Store)
19248 static const MCPhysReg ScratchRegs[] = {
19249 PPC::X12, PPC::LR8, PPC::CTR8, 0
19252 return ScratchRegs;
19256 const Constant *PersonalityFn)
const {
19257 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19261 const Constant *PersonalityFn)
const {
19262 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19267 EVT VT ,
unsigned DefinedValues)
const {
19268 if (VT == MVT::v2i64)
19269 return Subtarget.hasDirectMove();
19271 if (Subtarget.hasVSX())
19298 return PPCISD::FNMSUB;
19299 case PPCISD::FNMSUB:
19305 bool LegalOps,
bool OptForSize,
19307 unsigned Depth)
const {
19311 unsigned Opc =
Op.getOpcode();
19312 EVT VT =
Op.getValueType();
19316 case PPCISD::FNMSUB:
19336 if (Flags.hasNoSignedZeros()) {
19340 N0Cost,
Depth + 1);
19344 N1Cost,
Depth + 1);
19346 if (NegN0 && N0Cost <= N1Cost) {
19347 Cost = std::min(N0Cost, N2Cost);
19349 }
else if (NegN1) {
19350 Cost = std::min(N1Cost, N2Cost);
19370 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19376 bool ForCodeSize)
const {
19377 if (!VT.
isSimple() || !Subtarget.hasVSX())
19387 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19392 APSInt IntResult(16,
false);
19397 if (IsExact && IntResult <= 15 && IntResult >= -16)
19399 return Imm.isZero();
19402 return Imm.isPosZero();
19414 unsigned Opcode =
N->getOpcode();
19434 if (Mask->getZExtValue() == OpSizeInBits - 1)
19441 DAGCombinerInfo &DCI)
const {
19442 EVT VT =
N->getValueType(0);
19445 unsigned Opc =
N->getOpcode();
19447 "Unexpected opcode.");
19454 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19458 uint64_t SplatBits = 0;
19459 bool AddSplatCase =
false;
19463 AddSplatCase =
true;
19467 if (!AddSplatCase) {
19471 unsigned SplatBitSize;
19473 APInt APSplatBits, APSplatUndef;
19475 bool BVNIsConstantSplat =
19477 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19478 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19489 if (SplatBits == (EltBits - 1)) {
19493 NewOpc = PPCISD::SHL;
19496 NewOpc = PPCISD::SRL;
19499 NewOpc = PPCISD::SRA;
19503 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19511 if (EltTy != MVT::i64 || SplatBits != 1)
19514 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19517SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19521 if (
N->getValueType(0).isVector())
19522 return combineVectorShift(
N, DCI);
19526 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19529 N->getValueType(0) != MVT::i64)
19544 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19550SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19554 if (
N->getValueType(0).isVector())
19555 return combineVectorShift(
N, DCI);
19560SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19564 if (
N->getValueType(0).isVector())
19565 return combineVectorShift(
N, DCI);
19576 if (!Subtarget.isPPC64())
19582 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19584 Op.getValueType() != MVT::i64)
19588 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19589 Cmp.getOperand(0).getValueType() != MVT::i64)
19593 int64_t NegConstant = 0 -
Constant->getSExtValue();
19602 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19603 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19606 if (LHSHasPattern && !RHSHasPattern)
19608 else if (!LHSHasPattern && !RHSHasPattern)
19612 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19615 SDValue Z = Cmp.getOperand(0);
19617 int64_t NegConstant = 0 -
Constant->getSExtValue();
19630 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19648 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19678 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19681 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19689 if (!GSDN || !ConstNode)
19717 EVT VT =
N->getValueType(0);
19718 if (!Subtarget.hasVSX())
19722 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19734 unsigned NumOfEles =
RHS.getNumOperands();
19735 for (
unsigned i = 0; i < NumOfEles; ++i) {
19737 if (!CN || CN->getSExtValue() != 1)
19752SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19774 DAGCombinerInfo &DCI)
const {
19776 if (Subtarget.useCRBits()) {
19778 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19779 return CRTruncValue;
19786 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19789 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19799 EltToExtract = EltToExtract ? 0 : 1;
19809 return DCI.DAG.getNode(
19811 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19816SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19817 SelectionDAG &DAG = DCI.DAG;
19820 if (!ConstOpOrElement)
19828 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19829 switch (this->Subtarget.getCPUDirective()) {
19852 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19856 EVT VT =
N->getValueType(0);
19861 APInt MulAmtAbs = MulAmt.
abs();
19863 if ((MulAmtAbs - 1).isPowerOf2()) {
19867 if (!IsProfitable(IsNeg,
true, VT))
19880 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19884 if (!IsProfitable(IsNeg,
false, VT))
19905 DAGCombinerInfo &DCI)
const {
19909 SDNodeFlags
Flags =
N->getFlags();
19910 EVT VT =
N->getValueType(0);
19911 SelectionDAG &DAG = DCI.DAG;
19912 unsigned Opc =
N->getOpcode();
19914 bool LegalOps = !DCI.isBeforeLegalizeOps();
19922 if (!
Flags.hasNoSignedZeros())
19938bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19940 if (!Subtarget.is64BitELFABI())
19950 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19955 if (!Callee ||
Callee->isVarArg())
19968bool PPCTargetLowering::
19969isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19974 if (CI->getBitWidth() > 64)
19976 int64_t ConstVal = CI->getZExtValue();
19978 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19987PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19993 if ((Flags & FlagSet) == FlagSet)
19996 if ((Flags & FlagSet) == FlagSet)
19999 if ((Flags & FlagSet) == FlagSet)
20002 if ((Flags & FlagSet) == FlagSet)
20023 if ((FrameIndexAlign % 4) != 0)
20024 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20025 if ((FrameIndexAlign % 16) != 0)
20026 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20030 if ((FrameIndexAlign % 4) == 0)
20032 if ((FrameIndexAlign % 16) == 0)
20045 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20046 if ((Imm & 0x3) == 0)
20048 if ((Imm & 0xf) == 0)
20054 const APInt &ConstImm = CN->getAPIntValue();
20073 const APInt &ConstImm = CN->getAPIntValue();
20083 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20094 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20103unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20108 if (!Subtarget.hasP9Vector())
20113 if (Subtarget.hasPrefixInstrs())
20116 if (Subtarget.hasSPE())
20125 unsigned ParentOp = Parent->
getOpcode();
20129 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20130 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20142 if (LSB->isIndexed())
20148 assert(MN &&
"Parent should be a MemSDNode!");
20153 "Not expecting scalar integers larger than 16 bytes!");
20156 else if (
Size == 32)
20163 else if (
Size == 256) {
20164 assert(Subtarget.pairedVectorMemops() &&
20165 "256-bit vectors are only available when paired vector memops is "
20173 else if (MemVT == MVT::f128 || MemVT.
isVector())
20204 FlagSet &= ~PPC::MOF_NoExt;
20209 bool IsNonP1034BitConst =
20213 IsNonP1034BitConst)
20226 int16_t ForceXFormImm = 0;
20229 Disp =
N.getOperand(0);
20230 Base =
N.getOperand(1);
20241 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20242 Disp =
N.getOperand(0);
20243 Base =
N.getOperand(1);
20248 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20257 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20263 if (PartVT == MVT::f64 &&
20264 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20273SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20277 EVT RetVT =
Op.getValueType();
20284 EVT ArgVT =
N.getValueType();
20288 Entry.IsZExt = !Entry.IsSExt;
20289 Args.push_back(Entry);
20297 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20310SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20311 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20313 if (
Op.getValueType() == MVT::f32)
20314 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20316 if (
Op.getValueType() == MVT::f64)
20317 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20322bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20323 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20324 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20328bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20329 return Op.getNode()->getFlags().hasApproximateFuncs();
20332bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20336SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20337 const char *LibCallFloatName,
20338 const char *LibCallDoubleNameFinite,
20339 const char *LibCallFloatNameFinite,
20342 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20345 if (!isLowringToMASSFiniteSafe(
Op))
20346 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20349 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20350 LibCallDoubleNameFinite,
Op, DAG);
20354 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20355 "__xl_powf_finite",
Op, DAG);
20359 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20360 "__xl_sinf_finite",
Op, DAG);
20364 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20365 "__xl_cosf_finite",
Op, DAG);
20369 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20370 "__xl_logf_finite",
Op, DAG);
20374 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20375 "__xl_log10f_finite",
Op, DAG);
20379 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20380 "__xl_expf_finite",
Op, DAG);
20405 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20416 assert(Subtarget.isUsingPCRelativeCalls() &&
20417 "Must be using PC-Relative calls when a valid PC-Relative node is "
20447 Disp =
N.getOperand(1).getOperand(0);
20452 Base =
N.getOperand(0);
20460 EVT CNType = CN->getValueType(0);
20461 uint64_t CNImm = CN->getZExtValue();
20472 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20474 int32_t Addr = (int32_t)CNImm;
20479 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20495 unsigned Opcode =
N.getOpcode();
20503 Base =
N.getOperand(0);
20522 Base = FI ?
N :
N.getOperand(1);
20523 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20534 bool IsVarArg)
const {
20544 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20581 return Intrinsic::ppc_atomicrmw_xchg_i128;
20583 return Intrinsic::ppc_atomicrmw_add_i128;
20585 return Intrinsic::ppc_atomicrmw_sub_i128;
20587 return Intrinsic::ppc_atomicrmw_and_i128;
20589 return Intrinsic::ppc_atomicrmw_or_i128;
20591 return Intrinsic::ppc_atomicrmw_xor_i128;
20593 return Intrinsic::ppc_atomicrmw_nand_i128;
20601 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20603 assert(ValTy->getPrimitiveSizeInBits() == 128);
20605 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20607 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20608 Value *LoHi = Builder.CreateIntrinsic(
20610 {AlignedAddr, IncrLo, IncrHi});
20611 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20612 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20613 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20614 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20615 return Builder.CreateOr(
20616 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20623 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20625 assert(ValTy->getPrimitiveSizeInBits() == 128);
20629 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20631 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20632 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20634 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20637 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20639 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20640 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20641 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20642 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20643 return Builder.CreateOr(
20644 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20648 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.