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;
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);
11537 switch (
Op.getConstantOperandVal(ArgStart)) {
11538 case Intrinsic::ppc_cfence: {
11539 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11540 SDValue Val =
Op.getOperand(ArgStart + 1);
11542 if (Ty == MVT::i128) {
11547 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11550 Opcode,
DL, MVT::Other,
11555 case Intrinsic::ppc_mma_disassemble_dmr: {
11557 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11559 case Intrinsic::ppc_amo_stwat:
11560 case Intrinsic::ppc_amo_stdat: {
11563 SDValue Ptr =
Op.getOperand(ArgStart + 1);
11564 SDValue Val =
Op.getOperand(ArgStart + 2);
11567 return DAG.
getNode(PPCISD::STAT, dl, MVT::Other, Chain, Val, Ptr, FC);
11578 if (!Subtarget.isPPC64())
11586 int VectorIndex = 0;
11587 if (Subtarget.isLittleEndian())
11599 "Expecting an atomic compare-and-swap here.");
11602 EVT MemVT = AtomicNode->getMemoryVT();
11620 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11621 Ops.push_back(AtomicNode->getOperand(i));
11623 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11624 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11626 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11633 EVT MemVT =
N->getMemoryVT();
11635 "Expect quadword atomic operations");
11637 unsigned Opc =
N->getOpcode();
11642 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11645 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11646 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11647 Ops.push_back(
N->getOperand(
I));
11649 Ops, MemVT,
N->getMemOperand());
11656 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11663 SDVTList Tys = DAG.
getVTList(MVT::Other);
11666 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11672 Ops.push_back(ValLo);
11673 Ops.push_back(ValHi);
11674 Ops.push_back(
N->getOperand(2));
11676 N->getMemOperand());
11688 enum DataClassMask {
11690 DC_NEG_INF = 1 << 4,
11691 DC_POS_INF = 1 << 5,
11692 DC_NEG_ZERO = 1 << 2,
11693 DC_POS_ZERO = 1 << 3,
11694 DC_NEG_SUBNORM = 1,
11695 DC_POS_SUBNORM = 1 << 1,
11698 EVT VT =
Op.getValueType();
11700 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11701 : VT == MVT::f64 ? PPC::XSTSTDCDP
11712 return DAG.
getNOT(Dl, Rev, MVT::i1);
11719 TestOp, Dl, MVT::i32,
11721 DC_NEG_ZERO | DC_POS_ZERO |
11722 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11728 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11734 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11739 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11752 bool IsQuiet = Mask &
fcQNan;
11758 if (VT == MVT::f128) {
11762 QuietMask = 0x8000;
11763 }
else if (VT == MVT::f64) {
11764 if (Subtarget.isPPC64()) {
11775 QuietMask = 0x80000;
11776 }
else if (VT == MVT::f32) {
11778 QuietMask = 0x400000;
11794 unsigned NativeMask = 0;
11796 NativeMask |= DC_NAN;
11798 NativeMask |= DC_NEG_INF;
11800 NativeMask |= DC_POS_INF;
11802 NativeMask |= DC_NEG_ZERO;
11804 NativeMask |= DC_POS_ZERO;
11806 NativeMask |= DC_NEG_SUBNORM;
11808 NativeMask |= DC_POS_SUBNORM;
11811 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11813 TestOp, Dl, MVT::i32,
11822 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11824 uint64_t RHSC =
Op.getConstantOperandVal(1);
11827 if (
LHS.getValueType() == MVT::ppcf128) {
11851 bool Future = Subtarget.isISAFuture();
11854 "Mask predication not supported");
11857 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11858 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11862 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11865 VPLD->getMemoryVT(), VPLD->getMemOperand());
11872 "Mask predication not supported");
11877 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11878 bool Future = Subtarget.isISAFuture();
11879 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11882 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11885 SDVTList Tys = DAG.
getVTList(MVT::Other);
11888 VPST->getMemoryVT(), VPST->getMemOperand());
11899 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11901 int64_t
IntVal =
Op.getConstantOperandVal(0);
11902 if (IntVal >= -16 && IntVal <= 15)
11908 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11913 MachineMemOperand *MMO =
11915 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11918 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
11922 return Bits.getValue(0);
11938 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11943 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11950 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11951 MachinePointerInfo());
11958 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
11964 "Should only be called for ISD::INSERT_VECTOR_ELT");
11968 EVT VT =
Op.getValueType();
11973 if (VT == MVT::v2f64 &&
C)
11976 if (Subtarget.hasP9Vector()) {
11985 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
11991 BitcastLoad,
Op.getOperand(2));
11992 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11996 if (Subtarget.isISA3_1()) {
11997 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12001 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12002 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12012 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12015 unsigned InsertAtElement =
C->getZExtValue();
12016 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12017 if (Subtarget.isLittleEndian()) {
12018 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12020 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
12032 EVT VT =
Op.getValueType();
12033 bool IsV1024i1 = VT == MVT::v1024i1;
12034 bool IsV2048i1 = VT == MVT::v2048i1;
12038 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12040 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12041 "Dense Math support required.");
12042 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12051 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12052 MachineMemOperand *NewMMO =
12060 DAG.
getVTList(MVT::v256i1, MVT::Other),
12061 LoadOps, MVT::v256i1, NewMMO);
12066 if (Subtarget.isLittleEndian()) {
12067 std::reverse(Loads.
begin(), Loads.
end());
12068 std::reverse(LoadChains.
begin(), LoadChains.
end());
12080 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12086 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12089 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12098 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12101 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12106 {RC, Lo, LoSub, Hi, HiSub}),
12116 EVT VT =
Op.getValueType();
12118 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12119 return LowerDMFVectorLoad(
Op, DAG);
12121 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12127 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12128 "Type unsupported without MMA");
12129 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12130 "Type unsupported without paired vector support");
12135 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12137 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12146 if (Subtarget.isLittleEndian()) {
12147 std::reverse(Loads.
begin(), Loads.
end());
12148 std::reverse(LoadChains.
begin(), LoadChains.
end());
12152 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12168 bool IsV1024i1 = VT == MVT::v1024i1;
12169 bool IsV2048i1 = VT == MVT::v2048i1;
12173 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12175 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12176 "Dense Math support required.");
12177 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12179 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12182 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12187 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12191 MachineSDNode *ExtNode =
12195 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12201 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12207 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12213 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12218 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12223 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12228 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12232 MachineSDNode *ExtNode =
12233 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12237 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12240 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12244 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12249 if (Subtarget.isLittleEndian())
12250 std::reverse(Values.
begin(), Values.
end());
12252 SDVTList Tys = DAG.
getVTList(MVT::Other);
12254 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12258 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12259 MachineMemOperand *NewMMO =
12266 Ops[2] = Values[Idx];
12268 MVT::v256i1, NewMMO);
12284 EVT StoreVT =
Value.getValueType();
12286 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12287 return LowerDMFVectorStore(
Op, DAG);
12289 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12295 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12296 "Type unsupported without MMA");
12297 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12298 "Type unsupported without paired vector support");
12301 unsigned NumVecs = 2;
12302 if (StoreVT == MVT::v512i1) {
12303 if (Subtarget.isISAFuture()) {
12304 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12306 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12309 Value2 =
SDValue(ExtNode, 1);
12314 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12315 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12317 if (Subtarget.isISAFuture()) {
12318 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12319 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12320 Idx > 1 ? Value2 :
Value,
12323 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12327 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12341 if (
Op.getValueType() == MVT::v4i32) {
12358 LHS,
RHS, DAG, dl, MVT::v4i32);
12361 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12366 }
else if (
Op.getValueType() == MVT::v16i8) {
12368 bool isLittleEndian = Subtarget.isLittleEndian();
12372 LHS,
RHS, DAG, dl, MVT::v8i16);
12377 LHS,
RHS, DAG, dl, MVT::v8i16);
12385 for (
unsigned i = 0; i != 8; ++i) {
12386 if (isLittleEndian) {
12388 Ops[i*2+1] = 2*i+16;
12391 Ops[i*2+1] = 2*i+1+16;
12394 if (isLittleEndian)
12404 bool IsStrict =
Op->isStrictFPOpcode();
12405 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12406 !Subtarget.hasP9Vector())
12416 "Should only be called for ISD::FP_EXTEND");
12420 if (
Op.getValueType() != MVT::v2f64 ||
12421 Op.getOperand(0).getValueType() != MVT::v2f32)
12433 "Node should have 2 operands with second one being a constant!");
12445 int DWord = Idx >> 1;
12448 if (Subtarget.isLittleEndian())
12451 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12465 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12467 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12468 LD->getMemoryVT(),
LD->getMemOperand());
12473 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12478 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12480 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12481 LD->getMemoryVT(),
LD->getMemOperand());
12482 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12493 if (STI.useCRBits())
12510 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12511 if (STI.useCRBits())
12519 SDNode *
N =
Op.getNode();
12520 EVT VT =
N->getValueType(0);
12521 EVT CarryType =
N->getValueType(1);
12522 unsigned Opc =
N->getOpcode();
12524 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12526 N->getOperand(0),
N->getOperand(1));
12538 SDNode *
N =
Op.getNode();
12539 unsigned Opc =
N->getOpcode();
12540 EVT VT =
N->getValueType(0);
12541 EVT CarryType =
N->getValueType(1);
12542 SDValue CarryOp =
N->getOperand(2);
12544 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12550 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12564 EVT VT =
Op.getNode()->getValueType(0);
12590 EVT VT =
Op.getNode()->getValueType(0);
12619 EVT OpVT =
A.getValueType();
12620 EVT ResVT =
Op.getValueType();
12625 if (Subtarget.isPPC64() && OpVT == MVT::i32) {
12635 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12653 switch (
Op.getOpcode()) {
12673 return LowerSSUBO(
Op, DAG);
12675 return LowerSADDO(
Op, DAG);
12687 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12708 return LowerSET_ROUNDING(
Op, DAG);
12715 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12716 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12728 return LowerFP_ROUND(
Op, DAG);
12742 return LowerINTRINSIC_VOID(
Op, DAG);
12744 return LowerBSWAP(
Op, DAG);
12746 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12748 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12750 return LowerIS_FPCLASS(
Op, DAG);
12753 return LowerADDSUBO(
Op, DAG);
12756 return LowerADDSUBO_CARRY(
Op, DAG);
12758 return LowerUCMP(
Op, DAG);
12764 if (
Op->getFlags().hasNoFPExcept())
12768 return LowerVP_LOAD(
Op, DAG);
12769 case ISD::VP_STORE:
12770 return LowerVP_STORE(
Op, DAG);
12778 switch (
N->getOpcode()) {
12780 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12797 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12800 assert(
N->getValueType(0) == MVT::i1 &&
12801 "Unexpected result type for CTR decrement intrinsic");
12803 N->getValueType(0));
12813 switch (
N->getConstantOperandVal(0)) {
12814 case Intrinsic::ppc_pack_longdouble:
12816 N->getOperand(2),
N->getOperand(1)));
12818 case Intrinsic::ppc_maxfe:
12819 case Intrinsic::ppc_minfe:
12820 case Intrinsic::ppc_fnmsub:
12821 case Intrinsic::ppc_convert_f128_to_ppcf128:
12828 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12831 EVT VT =
N->getValueType(0);
12833 if (VT == MVT::i64) {
12846 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12850 Results.push_back(LoweredValue);
12851 if (
N->isStrictFPOpcode())
12856 if (!
N->getValueType(0).isVector())
12889 return Builder.CreateIntrinsic(Id, {});
12895 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12897 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12898 "Only 8/16/32/64-bit atomic loads supported");
12904 IntID = Intrinsic::ppc_lbarx;
12905 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12908 IntID = Intrinsic::ppc_lharx;
12909 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12912 IntID = Intrinsic::ppc_lwarx;
12915 IntID = Intrinsic::ppc_ldarx;
12919 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12921 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12932 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12933 "Only 8/16/32/64-bit atomic loads supported");
12939 IntID = Intrinsic::ppc_stbcx;
12940 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12943 IntID = Intrinsic::ppc_sthcx;
12944 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12947 IntID = Intrinsic::ppc_stwcx;
12950 IntID = Intrinsic::ppc_stdcx;
12954 if (SZ == 8 || SZ == 16)
12955 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
12957 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
12959 return Builder.CreateXor(
Call, Builder.getInt32(1));
12982 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
12992 unsigned AtomicSize,
12993 unsigned BinOpcode,
12994 unsigned CmpOpcode,
12995 unsigned CmpPred)
const {
12999 auto LoadMnemonic = PPC::LDARX;
13000 auto StoreMnemonic = PPC::STDCX;
13001 switch (AtomicSize) {
13005 LoadMnemonic = PPC::LBARX;
13006 StoreMnemonic = PPC::STBCX;
13007 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13010 LoadMnemonic = PPC::LHARX;
13011 StoreMnemonic = PPC::STHCX;
13012 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13015 LoadMnemonic = PPC::LWARX;
13016 StoreMnemonic = PPC::STWCX;
13019 LoadMnemonic = PPC::LDARX;
13020 StoreMnemonic = PPC::STDCX;
13036 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13038 F->insert(It, loopMBB);
13040 F->insert(It, loop2MBB);
13041 F->insert(It, exitMBB);
13047 Register TmpReg = (!BinOpcode) ? incr :
13048 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13049 : &PPC::GPRCRegClass);
13074 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13079 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13081 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13082 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13083 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13113 switch(
MI.getOpcode()) {
13117 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13118 &
MI.getMF()->getRegInfo());
13142 case PPC::EXTSB8_32_64:
13143 case PPC::EXTSB8_rec:
13144 case PPC::EXTSB_rec:
13147 case PPC::EXTSH8_32_64:
13148 case PPC::EXTSH8_rec:
13149 case PPC::EXTSH_rec:
13151 case PPC::EXTSWSLI:
13152 case PPC::EXTSWSLI_32_64:
13153 case PPC::EXTSWSLI_32_64_rec:
13154 case PPC::EXTSWSLI_rec:
13155 case PPC::EXTSW_32:
13156 case PPC::EXTSW_32_64:
13157 case PPC::EXTSW_32_64_rec:
13158 case PPC::EXTSW_rec:
13161 case PPC::SRAWI_rec:
13162 case PPC::SRAW_rec:
13171 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13181 bool IsSignExtended =
13184 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13185 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13186 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13187 .
addReg(
MI.getOperand(3).getReg());
13188 MI.getOperand(3).setReg(ValueReg);
13192 if (Subtarget.hasPartwordAtomics())
13200 bool is64bit = Subtarget.isPPC64();
13201 bool isLittleEndian = Subtarget.isLittleEndian();
13202 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13213 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13215 F->insert(It, loopMBB);
13217 F->insert(It, loop2MBB);
13218 F->insert(It, exitMBB);
13224 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13227 Register PtrReg = RegInfo.createVirtualRegister(RC);
13228 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13230 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13231 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13232 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13233 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13234 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13235 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13236 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13237 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13238 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13239 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13242 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13269 if (ptrA != ZeroReg) {
13270 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13271 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13279 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13280 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13283 .
addImm(is8bit ? 28 : 27);
13284 if (!isLittleEndian)
13285 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13287 .
addImm(is8bit ? 24 : 16);
13289 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13294 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13304 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13308 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13313 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13317 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13320 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13327 Register SReg = RegInfo.createVirtualRegister(GPRC);
13328 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13332 unsigned ValueReg = SReg;
13333 unsigned CmpReg = Incr2Reg;
13334 if (CmpOpcode == PPC::CMPW) {
13335 ValueReg = RegInfo.createVirtualRegister(GPRC);
13336 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13339 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13340 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13342 ValueReg = ValueSReg;
13374 .
addImm(is8bit ? 24 : 16)
13395 Register DstReg =
MI.getOperand(0).getReg();
13397 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13398 Register mainDstReg =
MRI.createVirtualRegister(RC);
13399 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13402 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13403 "Invalid Pointer Size!");
13451 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13452 Register BufReg =
MI.getOperand(1).getReg();
13454 if (Subtarget.is64BitELFABI()) {
13467 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13469 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13472 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13495 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13498 if (Subtarget.isPPC64()) {
13516 TII->get(PPC::PHI), DstReg)
13520 MI.eraseFromParent();
13534 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13535 "Invalid Pointer Size!");
13538 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13541 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13542 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13556 Register BufReg =
MI.getOperand(0).getReg();
13561 if (PVT == MVT::i64) {
13573 if (PVT == MVT::i64) {
13585 if (PVT == MVT::i64) {
13597 if (PVT == MVT::i64) {
13609 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13619 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13622 MI.eraseFromParent();
13638 "Unexpected stack alignment");
13642 unsigned StackProbeSize =
13645 StackProbeSize &= ~(StackAlign - 1);
13646 return StackProbeSize ? StackProbeSize : StackAlign;
13658 const bool isPPC64 = Subtarget.isPPC64();
13690 MF->
insert(MBBIter, TestMBB);
13691 MF->
insert(MBBIter, BlockMBB);
13692 MF->
insert(MBBIter, TailMBB);
13697 Register DstReg =
MI.getOperand(0).getReg();
13698 Register NegSizeReg =
MI.getOperand(1).getReg();
13700 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13701 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13702 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13708 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13710 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13716 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13717 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13719 .
addDef(ActualNegSizeReg)
13721 .
add(
MI.getOperand(2))
13722 .
add(
MI.getOperand(3));
13728 .
addReg(ActualNegSizeReg);
13731 int64_t NegProbeSize = -(int64_t)ProbeSize;
13733 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13735 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13737 .
addImm(NegProbeSize >> 16);
13741 .
addImm(NegProbeSize & 0xFFFF);
13748 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13750 .
addReg(ActualNegSizeReg)
13752 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13756 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13759 .
addReg(ActualNegSizeReg);
13768 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13769 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13794 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13796 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13797 MaxCallFrameSizeReg)
13798 .
add(
MI.getOperand(2))
13799 .
add(
MI.getOperand(3));
13800 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13802 .
addReg(MaxCallFrameSizeReg);
13808 MBB->addSuccessor(TestMBB);
13811 MI.eraseFromParent();
13813 ++NumDynamicAllocaProbed;
13818 switch (
MI.getOpcode()) {
13819 case PPC::SELECT_CC_I4:
13820 case PPC::SELECT_CC_I8:
13821 case PPC::SELECT_CC_F4:
13822 case PPC::SELECT_CC_F8:
13823 case PPC::SELECT_CC_F16:
13824 case PPC::SELECT_CC_VRRC:
13825 case PPC::SELECT_CC_VSFRC:
13826 case PPC::SELECT_CC_VSSRC:
13827 case PPC::SELECT_CC_VSRC:
13828 case PPC::SELECT_CC_SPE4:
13829 case PPC::SELECT_CC_SPE:
13837 switch (
MI.getOpcode()) {
13838 case PPC::SELECT_I4:
13839 case PPC::SELECT_I8:
13840 case PPC::SELECT_F4:
13841 case PPC::SELECT_F8:
13842 case PPC::SELECT_F16:
13843 case PPC::SELECT_SPE:
13844 case PPC::SELECT_SPE4:
13845 case PPC::SELECT_VRRC:
13846 case PPC::SELECT_VSFRC:
13847 case PPC::SELECT_VSSRC:
13848 case PPC::SELECT_VSRC:
13858 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13859 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13860 if (Subtarget.is64BitELFABI() &&
13861 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13862 !Subtarget.isUsingPCRelativeCalls()) {
13874 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13875 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13877 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13878 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13892 if (Subtarget.hasISEL() &&
13893 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13894 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13895 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13897 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13898 MI.getOpcode() == PPC::SELECT_CC_I8)
13899 Cond.push_back(
MI.getOperand(4));
13902 Cond.push_back(
MI.getOperand(1));
13905 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13906 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13922 F->insert(It, copy0MBB);
13923 F->insert(It, sinkMBB);
13932 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13947 .
addReg(
MI.getOperand(1).getReg())
13950 unsigned SelectPred =
MI.getOperand(4).getImm();
13953 .
addReg(
MI.getOperand(1).getReg())
13970 .
addReg(
MI.getOperand(3).getReg())
13972 .
addReg(
MI.getOperand(2).getReg())
13974 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13990 F->insert(It, readMBB);
13991 F->insert(It, sinkMBB);
14002 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14010 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14012 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14022 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
14024 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
14026 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
14028 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
14031 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
14033 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
14035 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
14037 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
14040 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
14042 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
14044 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
14046 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14049 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14051 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14053 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14055 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14058 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14060 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14062 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14064 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14067 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14069 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14071 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14073 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14076 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14078 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14080 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14082 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14085 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14087 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14089 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14091 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14094 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14096 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14098 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14100 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14103 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14105 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14107 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14109 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14112 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14114 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14116 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14118 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14120 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14121 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14122 (Subtarget.hasPartwordAtomics() &&
14123 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14124 (Subtarget.hasPartwordAtomics() &&
14125 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14126 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14128 auto LoadMnemonic = PPC::LDARX;
14129 auto StoreMnemonic = PPC::STDCX;
14130 switch (
MI.getOpcode()) {
14133 case PPC::ATOMIC_CMP_SWAP_I8:
14134 LoadMnemonic = PPC::LBARX;
14135 StoreMnemonic = PPC::STBCX;
14136 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14138 case PPC::ATOMIC_CMP_SWAP_I16:
14139 LoadMnemonic = PPC::LHARX;
14140 StoreMnemonic = PPC::STHCX;
14141 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14143 case PPC::ATOMIC_CMP_SWAP_I32:
14144 LoadMnemonic = PPC::LWARX;
14145 StoreMnemonic = PPC::STWCX;
14147 case PPC::ATOMIC_CMP_SWAP_I64:
14148 LoadMnemonic = PPC::LDARX;
14149 StoreMnemonic = PPC::STDCX;
14156 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14157 Register oldval =
MI.getOperand(3).getReg();
14158 Register newval =
MI.getOperand(4).getReg();
14164 F->insert(It, loop1MBB);
14165 F->insert(It, loop2MBB);
14166 F->insert(It, exitMBB);
14187 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14213 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14214 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14218 bool is64bit = Subtarget.isPPC64();
14219 bool isLittleEndian = Subtarget.isLittleEndian();
14220 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14225 Register oldval =
MI.getOperand(3).getReg();
14226 Register newval =
MI.getOperand(4).getReg();
14232 F->insert(It, loop1MBB);
14233 F->insert(It, loop2MBB);
14234 F->insert(It, exitMBB);
14241 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14244 Register PtrReg = RegInfo.createVirtualRegister(RC);
14245 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14247 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14248 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14249 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14250 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14251 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14252 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14253 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14254 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14255 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14256 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14257 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14259 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14260 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14261 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14292 if (ptrA != ZeroReg) {
14293 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14294 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14303 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14304 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14307 .
addImm(is8bit ? 28 : 27);
14308 if (!isLittleEndian)
14309 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14311 .
addImm(is8bit ? 24 : 16);
14313 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14318 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14323 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14326 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14333 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14337 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14340 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14343 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14348 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14365 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14389 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14399 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14414 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14422 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14423 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14424 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14425 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14426 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14427 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14430 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14431 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14434 Register Dest = RegInfo.createVirtualRegister(
14435 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14439 .
addReg(
MI.getOperand(1).getReg())
14442 MI.getOperand(0).getReg())
14443 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14444 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14447 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14450 MI.getOperand(0).getReg())
14452 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14454 unsigned Imm =
MI.getOperand(1).getImm();
14457 MI.getOperand(0).getReg())
14459 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14461 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14464 if (
MRI.use_empty(OldFPSCRReg))
14465 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14467 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14478 unsigned Mode =
MI.getOperand(1).getImm();
14479 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14483 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14486 }
else if (
MI.getOpcode() == PPC::SETRND) {
14494 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14495 if (Subtarget.hasDirectMove()) {
14496 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14500 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14503 if (RC == &PPC::F8RCRegClass) {
14505 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14506 "Unsupported RegClass.");
14508 StoreOp = PPC::STFD;
14512 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14513 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14514 "Unsupported RegClass.");
14547 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14550 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14562 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14564 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14566 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14567 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14572 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14573 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14578 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14579 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14585 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14586 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14595 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14599 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14600 if (
MRI.use_empty(OldFPSCRReg))
14601 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14603 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14606 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14612 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14613 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14615 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14622 .
addUse(Src, {}, PPC::sub_gp8_x1);
14625 .
addUse(Src, {}, PPC::sub_gp8_x0);
14626 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14627 MI.getOpcode() == PPC::STQX_PSEUDO) {
14633 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14639 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14640 :
TII->get(PPC::STQ))
14644 }
else if (
MI.getOpcode() == PPC::LWAT_PSEUDO ||
14645 MI.getOpcode() == PPC::LDAT_PSEUDO) {
14647 Register DstReg =
MI.getOperand(0).getReg();
14648 Register PtrReg =
MI.getOperand(1).getReg();
14649 Register ValReg =
MI.getOperand(2).getReg();
14650 unsigned FC =
MI.getOperand(3).getImm();
14651 bool IsLwat =
MI.getOpcode() == PPC::LWAT_PSEUDO;
14652 Register Val64 =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14654 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
14660 Register G8rPair =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14661 Register UndefG8r =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14662 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
14665 .
addImm(PPC::sub_gp8_x0)
14667 .
addImm(PPC::sub_gp8_x1);
14669 Register PairResult =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14670 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
14674 Register Result64 =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14676 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14679 .
addReg(Result64, {}, PPC::sub_32);
14683 }
else if (
MI.getOpcode() == PPC::LWAT_COND_PSEUDO ||
14684 MI.getOpcode() == PPC::LDAT_COND_PSEUDO) {
14686 Register DstReg =
MI.getOperand(0).getReg();
14687 Register PtrReg =
MI.getOperand(1).getReg();
14688 unsigned FC =
MI.getOperand(2).getImm();
14689 bool IsLwat_Cond =
MI.getOpcode() == PPC::LWAT_COND_PSEUDO;
14691 Register Pair =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14692 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), Pair);
14694 Register PairResult =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14695 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat_Cond ? PPC::LWAT : PPC::LDAT),
14700 Register Result64 =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14702 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14705 .
addReg(Result64, {}, PPC::sub_32);
14713 MI.eraseFromParent();
14726 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14729 return RefinementSteps;
14736 EVT VT =
Op.getValueType();
14739 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14763PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14766 EVT VT =
Op.getValueType();
14767 if (VT != MVT::f64 &&
14768 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14771 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14775 int Enabled,
int &RefinementSteps,
14776 bool &UseOneConstNR,
14777 bool Reciprocal)
const {
14779 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14780 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14781 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14782 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14788 UseOneConstNR = !Subtarget.needsTwoConstNR();
14789 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14796 int &RefinementSteps)
const {
14798 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14799 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14800 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14801 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14804 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14820 switch (Subtarget.getCPUDirective()) {
14847 unsigned Bytes,
int Dist,
14861 if (FS != BFS || FS != (
int)Bytes)
return false;
14866 int64_t Offset1 = 0, Offset2 = 0;
14869 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14879 if (isGA1 && isGA2 && GV1 == GV2)
14880 return Offset1 == (Offset2 + Dist*Bytes);
14887 unsigned Bytes,
int Dist,
14890 EVT VT = LS->getMemoryVT();
14897 switch (
N->getConstantOperandVal(1)) {
14898 default:
return false;
14899 case Intrinsic::ppc_altivec_lvx:
14900 case Intrinsic::ppc_altivec_lvxl:
14901 case Intrinsic::ppc_vsx_lxvw4x:
14902 case Intrinsic::ppc_vsx_lxvw4x_be:
14905 case Intrinsic::ppc_vsx_lxvd2x:
14906 case Intrinsic::ppc_vsx_lxvd2x_be:
14909 case Intrinsic::ppc_altivec_lvebx:
14912 case Intrinsic::ppc_altivec_lvehx:
14915 case Intrinsic::ppc_altivec_lvewx:
14925 switch (
N->getConstantOperandVal(1)) {
14926 default:
return false;
14927 case Intrinsic::ppc_altivec_stvx:
14928 case Intrinsic::ppc_altivec_stvxl:
14929 case Intrinsic::ppc_vsx_stxvw4x:
14932 case Intrinsic::ppc_vsx_stxvd2x:
14935 case Intrinsic::ppc_vsx_stxvw4x_be:
14938 case Intrinsic::ppc_vsx_stxvd2x_be:
14941 case Intrinsic::ppc_altivec_stvebx:
14944 case Intrinsic::ppc_altivec_stvehx:
14947 case Intrinsic::ppc_altivec_stvewx:
14964 SDValue Chain = LD->getChain();
14965 EVT VT = LD->getMemoryVT();
14974 while (!Queue.empty()) {
14975 SDNode *ChainNext = Queue.pop_back_val();
14976 if (!Visited.
insert(ChainNext).second)
14983 if (!Visited.
count(ChainLD->getChain().getNode()))
14984 Queue.push_back(ChainLD->getChain().getNode());
14986 for (
const SDUse &O : ChainNext->
ops())
14987 if (!Visited.
count(O.getNode()))
14988 Queue.push_back(O.getNode());
14990 LoadRoots.
insert(ChainNext);
15001 for (
SDNode *
I : LoadRoots) {
15002 Queue.push_back(
I);
15004 while (!Queue.empty()) {
15005 SDNode *LoadRoot = Queue.pop_back_val();
15006 if (!Visited.
insert(LoadRoot).second)
15018 Queue.push_back(U);
15051 auto Final = Shifted;
15062 DAGCombinerInfo &DCI)
const {
15065 SelectionDAG &DAG = DCI.DAG;
15070 if (!DCI.isAfterLegalizeDAG())
15075 for (
const SDNode *U :
N->users())
15080 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15084 if (OpSize <
Size) {
15102 DAGCombinerInfo &DCI)
const {
15103 SelectionDAG &DAG = DCI.DAG;
15106 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15117 N->getValueType(0) != MVT::i1)
15120 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15121 N->getOperand(0).getValueType() != MVT::i64)
15131 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15142 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15165 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15166 N->getOperand(0).getOpcode() !=
ISD::OR &&
15167 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15177 N->getOperand(1).getOpcode() !=
ISD::AND &&
15178 N->getOperand(1).getOpcode() !=
ISD::OR &&
15179 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15190 SmallPtrSet<SDNode *, 16> Visited;
15192 for (
unsigned i = 0; i < 2; ++i) {
15196 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15208 while (!BinOps.
empty()) {
15216 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15250 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15254 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15255 if (User !=
N && !Visited.
count(User))
15264 if (
User->getOperand(0) == Inputs[i])
15267 if (
User->getOperand(0) == Inputs[i] ||
15268 User->getOperand(1) == Inputs[i])
15274 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15275 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15276 if (User !=
N && !Visited.
count(User))
15285 if (
User->getOperand(0) == PromOps[i])
15288 if (
User->getOperand(0) == PromOps[i] ||
15289 User->getOperand(1) == PromOps[i])
15296 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15305 std::list<HandleSDNode> PromOpHandles;
15306 for (
auto &PromOp : PromOps)
15307 PromOpHandles.emplace_back(PromOp);
15314 while (!PromOpHandles.empty()) {
15315 SDValue PromOp = PromOpHandles.back().getValue();
15316 PromOpHandles.pop_back();
15325 PromOpHandles.emplace_front(PromOp);
15339 default:
C = 0;
break;
15352 PromOpHandles.emplace_front(PromOp);
15359 for (
unsigned i = 0; i < 2; ++i)
15369 return N->getOperand(0);
15377 DAGCombinerInfo &DCI)
const {
15378 SelectionDAG &DAG = DCI.DAG;
15395 if (
N->getValueType(0) != MVT::i32 &&
15396 N->getValueType(0) != MVT::i64)
15399 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15400 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15403 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15404 N->getOperand(0).getOpcode() !=
ISD::OR &&
15405 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15412 SmallPtrSet<SDNode *, 16> Visited;
15416 while (!BinOps.
empty()) {
15424 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15450 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15455 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15460 if (User !=
N && !Visited.
count(User))
15466 if (
User->getOperand(0) == Inputs[i])
15467 SelectTruncOp[0].
insert(std::make_pair(User,
15468 User->getOperand(0).getValueType()));
15470 if (
User->getOperand(0) == Inputs[i])
15471 SelectTruncOp[0].
insert(std::make_pair(User,
15472 User->getOperand(0).getValueType()));
15473 if (
User->getOperand(1) == Inputs[i])
15474 SelectTruncOp[1].
insert(std::make_pair(User,
15475 User->getOperand(1).getValueType()));
15480 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15482 if (User !=
N && !Visited.
count(User))
15488 if (
User->getOperand(0) == PromOps[i])
15489 SelectTruncOp[0].
insert(std::make_pair(User,
15490 User->getOperand(0).getValueType()));
15492 if (
User->getOperand(0) == PromOps[i])
15493 SelectTruncOp[0].
insert(std::make_pair(User,
15494 User->getOperand(0).getValueType()));
15495 if (
User->getOperand(1) == PromOps[i])
15496 SelectTruncOp[1].
insert(std::make_pair(User,
15497 User->getOperand(1).getValueType()));
15502 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15503 bool ReallyNeedsExt =
false;
15507 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15512 Inputs[i].getOperand(0).getValueSizeInBits();
15513 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15518 OpBits-PromBits))) ||
15521 (OpBits-(PromBits-1)))) {
15522 ReallyNeedsExt =
true;
15530 std::list<HandleSDNode> PromOpHandles;
15531 for (
auto &PromOp : PromOps)
15532 PromOpHandles.emplace_back(PromOp);
15536 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15543 SDValue InSrc = Inputs[i].getOperand(0);
15561 while (!PromOpHandles.empty()) {
15563 PromOpHandles.pop_back();
15567 default:
C = 0;
break;
15580 PromOpHandles.emplace_front(PromOp);
15590 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15592 PromOpHandles.emplace_front(PromOp);
15600 for (
unsigned i = 0; i < 2; ++i) {
15618 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15619 if (SI0 != SelectTruncOp[0].
end())
15621 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15622 if (SI1 != SelectTruncOp[1].
end())
15631 if (!ReallyNeedsExt)
15632 return N->getOperand(0);
15639 N->getValueSizeInBits(0), PromBits),
15640 dl,
N->getValueType(0)));
15643 "Invalid extension type");
15646 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15656 auto isValidForConvert = [](
SDValue &Operand) {
15675 if (LoadNode->isVolatile())
15696 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15706 "CC mus be ISD::SETNE or ISD::SETEQ");
15708 auto getV16i8Load = [&](
const SDValue &Operand) {
15715 return DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15716 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15755 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15756 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15759 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15762 IntrID, CRSel, LHSVec, RHSVec);
15765 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15783 auto IsAndWithOne = [](
SDValue &V) {
15794 auto IsCompareWithZero = [](
SDValue &V) {
15801 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15802 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15819 auto MakeXor1 = [&](
SDValue V) {
15820 EVT VT = V.getValueType();
15827 return MakeXor1(
LHS);
15830 return MakeXor1(
RHS);
15836 DAGCombinerInfo &DCI)
const {
15838 "Should be called with a SETCC node");
15860 SelectionDAG &DAG = DCI.DAG;
15861 EVT VT =
N->getValueType(0);
15862 EVT OpVT =
LHS.getValueType();
15884 return DAGCombineTruncBoolExt(
N, DCI);
15891 Op.getValueType() == MVT::f64;
15903combineElementTruncationToVectorTruncation(
SDNode *
N,
15904 DAGCombinerInfo &DCI)
const {
15906 "Should be called with a BUILD_VECTOR node");
15908 SelectionDAG &DAG = DCI.DAG;
15911 SDValue FirstInput =
N->getOperand(0);
15913 "The input operand must be an fp-to-int conversion.");
15918 if (FirstConversion == PPCISD::FCTIDZ ||
15919 FirstConversion == PPCISD::FCTIDUZ ||
15920 FirstConversion == PPCISD::FCTIWZ ||
15921 FirstConversion == PPCISD::FCTIWUZ) {
15922 bool IsSplat =
true;
15923 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
15924 FirstConversion == PPCISD::FCTIWUZ;
15927 EVT TargetVT =
N->getValueType(0);
15928 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15929 SDValue NextOp =
N->getOperand(i);
15930 if (NextOp.
getOpcode() != PPCISD::MFVSR)
15933 if (NextConversion != FirstConversion)
15941 if (
N->getOperand(i) != FirstInput)
15952 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15953 SDValue In =
N->getOperand(i).getOperand(0);
15963 Ops.push_back(Trunc);
15966 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
15970 if (FirstConversion == PPCISD::FCTIDZ ||
15971 FirstConversion == PPCISD::FCTIWZ)
15976 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15978 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15996 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16000 if (FullVal == BasePattern)
16001 return std::make_tuple(Uim,
uint8_t{0});
16004 if (FullVal ==
APInt(128, 1))
16005 return std::make_tuple(Uim,
uint8_t{127});
16007 return std::nullopt;
16027 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16031 EVT VT =
Op.getValueType();
16032 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16046 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16056 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16060 uint64_t ElemValue =
C->getZExtValue();
16064 ElemValue &= ((1ULL << ElemBits) - 1);
16068 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16071 APInt ElemAPInt(128, ElemValue);
16072 ElemAPInt <<= BitPos;
16075 FullVal |= ElemAPInt;
16082 const auto &[Uim, ShiftAmount] = *UIMOpt;
16086 if (ShiftAmount == 0) {
16091 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16092 LxvkqInstr.
dump());
16096 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16108 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16111 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16127 "Should be called with a BUILD_VECTOR node");
16132 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16135 bool InputsAreConsecutiveLoads =
true;
16136 bool InputsAreReverseConsecutive =
true;
16137 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16138 SDValue FirstInput =
N->getOperand(0);
16139 bool IsRoundOfExtLoad =
false;
16149 N->getNumOperands() == 1)
16152 if (!IsRoundOfExtLoad)
16157 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16159 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16162 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16168 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16179 InputsAreConsecutiveLoads =
false;
16181 InputsAreReverseConsecutive =
false;
16184 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16189 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16190 "The loads cannot be both consecutive and reverse consecutive.");
16194 if (InputsAreConsecutiveLoads) {
16195 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16199 ReturnSDVal = WideLoad;
16200 }
else if (InputsAreReverseConsecutive) {
16202 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16207 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16215 for (
auto *LD : InputLoads)
16217 return ReturnSDVal;
16228 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16234 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16236 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16238 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16239 CorrectElems = CorrectElems >> 8;
16240 Elems = Elems >> 8;
16247 EVT VT =
N->getValueType(0);
16251 Input.getValueType().getVectorElementType(),
16285 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16311 Elems = Elems << 8;
16320 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16321 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16328 int TgtElemArrayIdx;
16329 int InputSize =
Input.getValueType().getScalarSizeInBits();
16330 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16331 if (InputSize + OutputSize == 40)
16332 TgtElemArrayIdx = 0;
16333 else if (InputSize + OutputSize == 72)
16334 TgtElemArrayIdx = 1;
16335 else if (InputSize + OutputSize == 48)
16336 TgtElemArrayIdx = 2;
16337 else if (InputSize + OutputSize == 80)
16338 TgtElemArrayIdx = 3;
16339 else if (InputSize + OutputSize == 96)
16340 TgtElemArrayIdx = 4;
16344 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16346 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16347 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16348 if (Elems != CorrectElems) {
16364 if (
N->getValueType(0) != MVT::v1i128)
16367 SDValue Operand =
N->getOperand(0);
16374 EVT MemoryType = LD->getMemoryVT();
16378 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16379 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16382 if (!ValidLDType ||
16388 LD->getChain(), LD->getBasePtr(),
16392 DAG.
getVTList(MVT::v1i128, MVT::Other),
16393 LoadOps, MemoryType, LD->getMemOperand());
16397 DAGCombinerInfo &DCI)
const {
16399 "Should be called with a BUILD_VECTOR node");
16401 SelectionDAG &DAG = DCI.DAG;
16404 if (!Subtarget.hasVSX())
16411 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16412 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16427 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16436 if (Subtarget.isISA3_1()) {
16442 if (
N->getValueType(0) != MVT::v2f64)
16453 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16464 if (!Ext1Op || !Ext2Op)
16473 if (FirstElem == 0 && SecondElem == 1)
16474 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16475 else if (FirstElem == 2 && SecondElem == 3)
16476 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16482 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16483 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16488 DAGCombinerInfo &DCI)
const {
16491 "Need an int -> FP conversion node here");
16496 SelectionDAG &DAG = DCI.DAG;
16502 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16504 if (!
Op.getOperand(0).getValueType().isSimple())
16506 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16507 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16510 SDValue FirstOperand(
Op.getOperand(0));
16511 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16512 (FirstOperand.getValueType() == MVT::i8 ||
16513 FirstOperand.getValueType() == MVT::i16);
16514 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16516 bool DstDouble =
Op.getValueType() == MVT::f64;
16517 unsigned ConvOp =
Signed ?
16518 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16519 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16524 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16527 Ops, MVT::i8, LDN->getMemOperand());
16532 SDValue ExtOps[] = { Ld, WidthConst };
16534 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16536 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16544 if (
Op.getOperand(0).getValueType() == MVT::i32)
16548 "UINT_TO_FP is supported only with FPCVT");
16552 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16557 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16564 Subtarget.hasFPCVT()) ||
16566 SDValue Src =
Op.getOperand(0).getOperand(0);
16567 if (Src.getValueType() == MVT::f32) {
16569 DCI.AddToWorklist(Src.getNode());
16570 }
else if (Src.getValueType() != MVT::f64) {
16582 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16585 DCI.AddToWorklist(
FP.getNode());
16609 switch (
N->getOpcode()) {
16614 Chain = LD->getChain();
16615 Base = LD->getBasePtr();
16616 MMO = LD->getMemOperand();
16635 MVT VecTy =
N->getValueType(0).getSimpleVT();
16643 Chain = Load.getValue(1);
16645 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16649 if (VecTy != MVT::v2f64) {
16676 switch (
N->getOpcode()) {
16681 Chain = ST->getChain();
16682 Base = ST->getBasePtr();
16683 MMO = ST->getMemOperand();
16703 SDValue Src =
N->getOperand(SrcOpnd);
16704 MVT VecTy = Src.getValueType().getSimpleVT();
16707 if (VecTy != MVT::v2f64) {
16713 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16719 StoreOps, VecTy, MMO);
16726 DAGCombinerInfo &DCI)
const {
16729 unsigned Opcode =
N->getOperand(1).getOpcode();
16731 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16735 &&
"Not a FP_TO_INT Instruction!");
16737 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16738 EVT Op1VT =
N->getOperand(1).getValueType();
16741 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16745 bool ValidTypeForStoreFltAsInt =
16746 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16747 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16750 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16753 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16761 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16776 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16777 for (
int i = 1, e = Mask.size(); i < e; i++) {
16778 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16780 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16782 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16793 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16794 FirstOp =
Op.getOperand(i);
16800 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16801 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16811 Op =
Op.getOperand(0);
16827 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16828 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16830 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16832 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16833 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16834 int Idx = ShuffV[
I];
16835 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16836 ShuffV[
I] += LHSEltFixup;
16837 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16838 ShuffV[
I] += RHSEltFixup;
16849 SDLoc dl(OrigSToV);
16852 "Expecting a SCALAR_TO_VECTOR here");
16865 "Cannot produce a permuted scalar_to_vector for one element vector");
16867 unsigned ResultInElt = NumElts / 2;
16873 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
16878 int HalfVec,
int LHSLastElementDefined,
16879 int RHSLastElementDefined) {
16880 for (
int Index : ShuffV) {
16884 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16885 (Index > LHSLastElementDefined))
16888 if ((RHSLastElementDefined >= 0) &&
16889 (Index > HalfVec + RHSLastElementDefined))
16896 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16897 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16913 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16914 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16917 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16918 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16919 return SToVPermuted;
16939 int NumElts =
LHS.getValueType().getVectorNumElements();
16942 bool IsLittleEndian = Subtarget.isLittleEndian();
16949 if (!Subtarget.hasDirectMove())
16969 SmallVector<int, 16> ShuffV(Mask);
16972 if (SToVLHS || SToVRHS) {
16975 int ShuffleNumElts = ShuffV.
size();
16976 int HalfVec = ShuffleNumElts / 2;
16982 unsigned LHSNumValidElts = HalfVec;
16983 unsigned RHSNumValidElts = HalfVec;
16988 int LHSFirstElt = 0;
16989 int RHSFirstElt = ShuffleNumElts;
16990 int LHSLastElt = -1;
16991 int RHSLastElt = -1;
16999 int LHSScalarSize = 0;
17000 int RHSScalarSize = 0;
17003 if (!IsLittleEndian && LHSScalarSize >= 64)
17008 if (!IsLittleEndian && RHSScalarSize >= 64)
17011 if (LHSScalarSize != 0)
17013 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17014 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17015 if (RHSScalarSize != 0)
17017 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17018 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17029 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17030 LHSNumValidElts, RHSNumValidElts, Subtarget);
17056 if (IsLittleEndian) {
17059 if (Mask[0] < NumElts)
17060 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17064 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17069 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17073 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17078 if (Mask[0] < NumElts)
17079 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17083 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17088 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17092 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17102 if (IsLittleEndian)
17111 DAGCombinerInfo &DCI)
const {
17113 "Not a reverse memop pattern!");
17115 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17118 auto I =
Mask.rbegin();
17119 auto E =
Mask.rend();
17121 for (;
I !=
E; ++
I) {
17129 SelectionDAG &DAG = DCI.DAG;
17132 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17138 if (!Subtarget.hasP9Vector())
17141 if(!IsElementReverse(SVN))
17148 for (SDUse &Use : LSBase->
uses())
17149 if (
Use.getResNo() == 0 &&
17156 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17171 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17180 if (IntrinsicID == Intrinsic::ppc_stdcx)
17182 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17184 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17186 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17195 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17199 if (
LHS->getOpcode() == PPCISD::ADDE &&
17251 auto isZeroOrOne = [=](
SDValue &V) {
17253 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17258 if (!isZeroOrOne(NonNullConstant))
17268 EVT VType =
N->getValueType(0);
17272 return NewNonNullConstant;
17291 EVT XorVT =
N->getValueType(0);
17292 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17300 if (!XorConst || !XorConst->
isOne()) {
17302 if (!XorConst || !XorConst->
isOne())
17309 if (!
LHS.hasOneUse())
17317 SelectNode =
LHS.getOperand(0);
17331 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17341 if (!ConstOp1 || !ConstOp2)
17345 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17354 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17356 bool ConstOp1IsOne = ConstOp1->
isOne();
17359 {SelectNode.getOperand(0),
17360 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17361 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17362 SelectNode.getOperand(3)}),
17370 switch (
N->getOpcode()) {
17373 return combineADD(
N, DCI);
17405 return combineSHL(
N, DCI);
17407 return combineSRA(
N, DCI);
17409 return combineSRL(
N, DCI);
17411 return combineMUL(
N, DCI);
17413 case PPCISD::FNMSUB:
17414 return combineFMALike(
N, DCI);
17417 return N->getOperand(0);
17421 return N->getOperand(0);
17427 return N->getOperand(0);
17436 return DAGCombineExtBoolTrunc(
N, DCI);
17438 return combineTRUNCATE(
N, DCI);
17440 if (
SDValue CSCC = combineSetCC(
N, DCI))
17444 return DAGCombineTruncBoolExt(
N, DCI);
17447 return combineFPToIntToFP(
N, DCI);
17456 EVT Op1VT =
N->getOperand(1).getValueType();
17457 unsigned Opcode =
N->getOperand(1).getOpcode();
17461 SDValue Val = combineStoreFPToInt(
N, DCI);
17475 N->getOperand(1).getNode()->hasOneUse() &&
17476 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17477 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17485 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17492 if (Op1VT.
bitsGT(mVT)) {
17497 if (Op1VT == MVT::i64)
17502 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17522 ST->getBasePtr(), ST->getOffset(), MemVT,
17523 ST->getMemOperand(), ST->getAddressingMode(),
17527 return ST->isUnindexed()
17536 if (Subtarget.needsSwapsForVSXMemOps() &&
17537 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17538 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17545 EVT VT = LD->getValueType(0);
17551 if (Subtarget.needsSwapsForVSXMemOps() &&
17552 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17553 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17564 auto ReplaceTwoFloatLoad = [&]() {
17565 if (VT != MVT::i64)
17580 if (!LD->hasNUsesOfValue(2, 0))
17583 auto UI = LD->user_begin();
17584 while (UI.getUse().getResNo() != 0) ++UI;
17586 while (UI.getUse().getResNo() != 0) ++UI;
17587 SDNode *RightShift = *UI;
17595 if (RightShift->getOpcode() !=
ISD::SRL ||
17597 RightShift->getConstantOperandVal(1) != 32 ||
17598 !RightShift->hasOneUse())
17601 SDNode *Trunc2 = *RightShift->user_begin();
17611 Bitcast->getValueType(0) != MVT::f32)
17617 if (Subtarget.isLittleEndian())
17623 SDValue BasePtr = LD->getBasePtr();
17624 if (LD->isIndexed()) {
17626 "Non-pre-inc AM on PPC?");
17634 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17635 LD->getPointerInfo(), LD->getAlign(),
17636 MMOFlags, LD->getAAInfo());
17642 LD->getPointerInfo().getWithOffset(4),
17645 if (LD->isIndexed()) {
17659 if (ReplaceTwoFloatLoad())
17662 EVT MemVT = LD->getMemoryVT();
17665 if (LD->isUnindexed() && VT.
isVector() &&
17668 !Subtarget.hasP8Vector() &&
17669 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17670 VT == MVT::v4f32))) &&
17671 LD->getAlign() < ABIAlignment) {
17673 SDValue Chain = LD->getChain();
17674 SDValue Ptr = LD->getBasePtr();
17675 bool isLittleEndian = Subtarget.isLittleEndian();
17702 MVT PermCntlTy, PermTy, LDTy;
17703 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17704 : Intrinsic::ppc_altivec_lvsl;
17705 IntrLD = Intrinsic::ppc_altivec_lvx;
17706 IntrPerm = Intrinsic::ppc_altivec_vperm;
17707 PermCntlTy = MVT::v16i8;
17708 PermTy = MVT::v4i32;
17727 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
17731 BaseLoadOps, LDTy, BaseMMO);
17740 int IncValue = IncOffset;
17757 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
17761 ExtraLoadOps, LDTy, ExtraMMO);
17772 if (isLittleEndian)
17774 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17777 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17780 Perm = Subtarget.hasAltivec()
17795 bool isLittleEndian = Subtarget.isLittleEndian();
17796 unsigned IID =
N->getConstantOperandVal(0);
17797 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17798 : Intrinsic::ppc_altivec_lvsl);
17799 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17806 .zext(
Add.getScalarValueSizeInBits()))) {
17807 SDNode *BasePtr =
Add->getOperand(0).getNode();
17808 for (
SDNode *U : BasePtr->users()) {
17810 U->getConstantOperandVal(0) == IID) {
17821 SDNode *BasePtr =
Add->getOperand(0).getNode();
17822 for (
SDNode *U : BasePtr->users()) {
17825 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17831 V->getConstantOperandVal(0) == IID) {
17843 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17844 IID == Intrinsic::ppc_altivec_vmaxsh ||
17845 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17876 switch (
N->getConstantOperandVal(1)) {
17879 case Intrinsic::ppc_altivec_vsum4sbs:
17880 case Intrinsic::ppc_altivec_vsum4shs:
17881 case Intrinsic::ppc_altivec_vsum4ubs: {
17888 APInt APSplatBits, APSplatUndef;
17889 unsigned SplatBitSize;
17892 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17893 !Subtarget.isLittleEndian());
17895 if (BVNIsConstantSplat && APSplatBits == 0)
17900 case Intrinsic::ppc_vsx_lxvw4x:
17901 case Intrinsic::ppc_vsx_lxvd2x:
17904 if (Subtarget.needsSwapsForVSXMemOps())
17912 if (Subtarget.needsSwapsForVSXMemOps()) {
17913 switch (
N->getConstantOperandVal(1)) {
17916 case Intrinsic::ppc_vsx_stxvw4x:
17917 case Intrinsic::ppc_vsx_stxvd2x:
17926 bool Is64BitBswapOn64BitTgt =
17927 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17929 N->getOperand(0).hasOneUse();
17930 if (IsSingleUseNormalLd &&
17931 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17932 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17943 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17944 MVT::i64 : MVT::i32, MVT::Other),
17945 Ops, LD->getMemoryVT(), LD->getMemOperand());
17949 if (
N->getValueType(0) == MVT::i16)
17966 !IsSingleUseNormalLd)
17971 if (!LD->isSimple())
17973 SDValue BasePtr = LD->getBasePtr();
17975 LD->getPointerInfo(), LD->getAlign());
17980 LD->getMemOperand(), 4, 4);
17984 if (Subtarget.isLittleEndian())
17990 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
17999 if (!
N->getOperand(0).hasOneUse() &&
18000 !
N->getOperand(1).hasOneUse() &&
18001 !
N->getOperand(2).hasOneUse()) {
18004 SDNode *VCMPrecNode =
nullptr;
18006 SDNode *LHSN =
N->getOperand(0).getNode();
18008 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18012 VCMPrecNode =
User;
18024 SDNode *FlagUser =
nullptr;
18026 FlagUser ==
nullptr; ++UI) {
18027 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18040 return SDValue(VCMPrecNode, 0);
18051 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18062 auto RHSAPInt = RHS->getAsAPIntVal();
18063 if (!RHSAPInt.isIntN(64))
18066 unsigned Val = RHSAPInt.getZExtValue();
18067 auto isImpossibleCompare = [&]() {
18070 if (Val != 0 && Val != 1) {
18072 return N->getOperand(0);
18075 N->getOperand(0),
N->getOperand(4));
18080 unsigned StoreWidth = 0;
18083 if (
SDValue Impossible = isImpossibleCompare())
18095 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18099 PPCISD::STORE_COND, dl,
18101 MemNode->getMemoryVT(), MemNode->getMemOperand());
18105 if (
N->getOperand(0) == LHS.getValue(1))
18116 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18118 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18124 assert(isDot &&
"Can't compare against a vector result!");
18126 if (
SDValue Impossible = isImpossibleCompare())
18129 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18136 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18141 switch (LHS.getConstantOperandVal(1)) {
18157 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18160 N->getOperand(4), CompNode.
getValue(1));
18165 return DAGCombineBuildVector(
N, DCI);
18178 EVT VT =
N->getValueType(0);
18179 if (VT == MVT::i64 && !Subtarget.isPPC64())
18181 if ((VT != MVT::i32 && VT != MVT::i64) ||
18189 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18209 const APInt &DemandedElts,
18211 unsigned Depth)
const {
18213 switch (
Op.getOpcode()) {
18215 case PPCISD::LBRX: {
18218 Known.
Zero = 0xFFFF0000;
18221 case PPCISD::ADDE: {
18222 if (
Op.getResNo() == 0) {
18227 Known.
Zero = ~1ULL;
18232 switch (
Op.getConstantOperandVal(0)) {
18234 case Intrinsic::ppc_altivec_vcmpbfp_p:
18235 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18236 case Intrinsic::ppc_altivec_vcmpequb_p:
18237 case Intrinsic::ppc_altivec_vcmpequh_p:
18238 case Intrinsic::ppc_altivec_vcmpequw_p:
18239 case Intrinsic::ppc_altivec_vcmpequd_p:
18240 case Intrinsic::ppc_altivec_vcmpequq_p:
18241 case Intrinsic::ppc_altivec_vcmpgefp_p:
18242 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18243 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18244 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18245 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18246 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18247 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18248 case Intrinsic::ppc_altivec_vcmpgtub_p:
18249 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18250 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18251 case Intrinsic::ppc_altivec_vcmpgtud_p:
18252 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18259 switch (
Op.getConstantOperandVal(1)) {
18262 case Intrinsic::ppc_load2r:
18264 Known.
Zero = 0xFFFF0000;
18273 switch (Subtarget.getCPUDirective()) {
18295 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18304 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18306 LoopSize +=
TII->getInstSizeInBytes(J);
18311 if (LoopSize > 16 && LoopSize <= 32)
18325 if (Constraint.
size() == 1) {
18326 switch (Constraint[0]) {
18344 }
else if (Constraint ==
"wc") {
18346 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18347 Constraint ==
"wf" || Constraint ==
"ws" ||
18348 Constraint ==
"wi" || Constraint ==
"ww") {
18361 Value *CallOperandVal =
info.CallOperandVal;
18364 if (!CallOperandVal)
18371 else if ((
StringRef(constraint) ==
"wa" ||
18383 switch (*constraint) {
18413std::pair<unsigned, const TargetRegisterClass *>
18417 if (Constraint.
size() == 1) {
18419 switch (Constraint[0]) {
18421 if (VT == MVT::i64 && Subtarget.isPPC64())
18422 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18423 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18425 if (VT == MVT::i64 && Subtarget.isPPC64())
18426 return std::make_pair(0U, &PPC::G8RCRegClass);
18427 return std::make_pair(0U, &PPC::GPRCRegClass);
18433 if (Subtarget.hasSPE()) {
18434 if (VT == MVT::f32 || VT == MVT::i32)
18435 return std::make_pair(0U, &PPC::GPRCRegClass);
18436 if (VT == MVT::f64 || VT == MVT::i64)
18437 return std::make_pair(0U, &PPC::SPERCRegClass);
18439 if (VT == MVT::f32 || VT == MVT::i32)
18440 return std::make_pair(0U, &PPC::F4RCRegClass);
18441 if (VT == MVT::f64 || VT == MVT::i64)
18442 return std::make_pair(0U, &PPC::F8RCRegClass);
18446 if (Subtarget.hasAltivec() && VT.
isVector())
18447 return std::make_pair(0U, &PPC::VRRCRegClass);
18448 else if (Subtarget.hasVSX())
18450 return std::make_pair(0U, &PPC::VFRCRegClass);
18453 return std::make_pair(0U, &PPC::CRRCRegClass);
18455 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18457 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18458 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18459 Constraint ==
"wf" || Constraint ==
"wi") &&
18460 Subtarget.hasVSX()) {
18464 return std::make_pair(0U, &PPC::VSRCRegClass);
18465 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18466 return std::make_pair(0U, &PPC::VSSRCRegClass);
18467 return std::make_pair(0U, &PPC::VSFRCRegClass);
18468 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18469 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18470 return std::make_pair(0U, &PPC::VSSRCRegClass);
18472 return std::make_pair(0U, &PPC::VSFRCRegClass);
18473 }
else if (Constraint ==
"lr") {
18474 if (VT == MVT::i64)
18475 return std::make_pair(0U, &PPC::LR8RCRegClass);
18477 return std::make_pair(0U, &PPC::LRRCRegClass);
18482 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18486 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18487 int VSNum = atoi(Constraint.
data() + 3);
18488 assert(VSNum >= 0 && VSNum <= 63 &&
18489 "Attempted to access a vsr out of range");
18491 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18492 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18497 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18498 int RegNum = atoi(Constraint.
data() + 2);
18499 if (RegNum > 31 || RegNum < 0)
18501 if (VT == MVT::f32 || VT == MVT::i32)
18502 return Subtarget.hasSPE()
18503 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18504 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18505 if (VT == MVT::f64 || VT == MVT::i64)
18506 return Subtarget.hasSPE()
18507 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18508 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18512 std::pair<unsigned, const TargetRegisterClass *> R =
18521 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18522 PPC::GPRCRegClass.contains(R.first))
18523 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18524 PPC::sub_32, &PPC::G8RCRegClass),
18525 &PPC::G8RCRegClass);
18528 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18529 R.first = PPC::CR0;
18530 R.second = &PPC::CRRCRegClass;
18534 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18535 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18536 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18537 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18538 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18539 "default AIX AltiVec ABI and cannot be used\n";
18549 std::vector<SDValue> &
Ops,
18554 if (Constraint.
size() > 1)
18557 char Letter = Constraint[0];
18572 EVT TCVT = MVT::i64;
18613 if (Result.getNode()) {
18614 Ops.push_back(Result);
18625 if (
I.getNumOperands() <= 1)
18629 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18630 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18631 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18634 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18650 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18662 switch (AM.
Scale) {
18690 unsigned Depth =
Op.getConstantOperandVal(0);
18714 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18722 unsigned Depth =
Op.getConstantOperandVal(0);
18729 bool isPPC64 = PtrVT == MVT::i64;
18735 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18737 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18743 FrameAddr, MachinePointerInfo());
18747#define GET_REGISTER_MATCHER
18748#include "PPCGenAsmMatcher.inc"
18752 bool IsPPC64 = Subtarget.isPPC64();
18764 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18770 Reg = Reg.id() - PPC::R0 + PPC::X0;
18777 if (Subtarget.is32BitELFABI())
18782 if (Subtarget.isAIXABI())
18796 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18812 case Intrinsic::ppc_atomicrmw_xchg_i128:
18813 case Intrinsic::ppc_atomicrmw_add_i128:
18814 case Intrinsic::ppc_atomicrmw_sub_i128:
18815 case Intrinsic::ppc_atomicrmw_nand_i128:
18816 case Intrinsic::ppc_atomicrmw_and_i128:
18817 case Intrinsic::ppc_atomicrmw_or_i128:
18818 case Intrinsic::ppc_atomicrmw_xor_i128:
18819 case Intrinsic::ppc_cmpxchg_i128:
18821 Info.memVT = MVT::i128;
18822 Info.ptrVal =
I.getArgOperand(0);
18824 Info.align =
Align(16);
18829 case Intrinsic::ppc_atomic_load_i128:
18831 Info.memVT = MVT::i128;
18832 Info.ptrVal =
I.getArgOperand(0);
18834 Info.align =
Align(16);
18838 case Intrinsic::ppc_atomic_store_i128:
18840 Info.memVT = MVT::i128;
18841 Info.ptrVal =
I.getArgOperand(2);
18843 Info.align =
Align(16);
18847 case Intrinsic::ppc_altivec_lvx:
18848 case Intrinsic::ppc_altivec_lvxl:
18849 case Intrinsic::ppc_altivec_lvebx:
18850 case Intrinsic::ppc_altivec_lvehx:
18851 case Intrinsic::ppc_altivec_lvewx:
18852 case Intrinsic::ppc_vsx_lxvd2x:
18853 case Intrinsic::ppc_vsx_lxvw4x:
18854 case Intrinsic::ppc_vsx_lxvd2x_be:
18855 case Intrinsic::ppc_vsx_lxvw4x_be:
18856 case Intrinsic::ppc_vsx_lxvl:
18857 case Intrinsic::ppc_vsx_lxvll: {
18860 case Intrinsic::ppc_altivec_lvebx:
18863 case Intrinsic::ppc_altivec_lvehx:
18866 case Intrinsic::ppc_altivec_lvewx:
18869 case Intrinsic::ppc_vsx_lxvd2x:
18870 case Intrinsic::ppc_vsx_lxvd2x_be:
18880 Info.ptrVal =
I.getArgOperand(0);
18883 Info.align =
Align(1);
18888 case Intrinsic::ppc_altivec_stvx:
18889 case Intrinsic::ppc_altivec_stvxl:
18890 case Intrinsic::ppc_altivec_stvebx:
18891 case Intrinsic::ppc_altivec_stvehx:
18892 case Intrinsic::ppc_altivec_stvewx:
18893 case Intrinsic::ppc_vsx_stxvd2x:
18894 case Intrinsic::ppc_vsx_stxvw4x:
18895 case Intrinsic::ppc_vsx_stxvd2x_be:
18896 case Intrinsic::ppc_vsx_stxvw4x_be:
18897 case Intrinsic::ppc_vsx_stxvl:
18898 case Intrinsic::ppc_vsx_stxvll: {
18901 case Intrinsic::ppc_altivec_stvebx:
18904 case Intrinsic::ppc_altivec_stvehx:
18907 case Intrinsic::ppc_altivec_stvewx:
18910 case Intrinsic::ppc_vsx_stxvd2x:
18911 case Intrinsic::ppc_vsx_stxvd2x_be:
18921 Info.ptrVal =
I.getArgOperand(1);
18924 Info.align =
Align(1);
18929 case Intrinsic::ppc_stdcx:
18930 case Intrinsic::ppc_stwcx:
18931 case Intrinsic::ppc_sthcx:
18932 case Intrinsic::ppc_stbcx: {
18934 auto Alignment =
Align(8);
18936 case Intrinsic::ppc_stdcx:
18939 case Intrinsic::ppc_stwcx:
18941 Alignment =
Align(4);
18943 case Intrinsic::ppc_sthcx:
18945 Alignment =
Align(2);
18947 case Intrinsic::ppc_stbcx:
18949 Alignment =
Align(1);
18954 Info.ptrVal =
I.getArgOperand(0);
18956 Info.align = Alignment;
18970 const AttributeList &FuncAttributes)
const {
18974 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
18975 if (
Op.isMemset() && Subtarget.hasVSX()) {
18980 if (TailSize > 2 && TailSize <= 4) {
18985 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
18990 if (Subtarget.isPPC64()) {
19001 assert(Ty->isIntegerTy());
19003 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19004 return !(BitSize == 0 || BitSize > 64);
19012 return NumBits1 == 64 && NumBits2 == 32;
19020 return NumBits1 == 64 && NumBits2 == 32;
19027 EVT MemVT = LD->getMemoryVT();
19028 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19029 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19045 "invalid fpext types");
19047 if (DestVT == MVT::f128)
19062 unsigned *
Fast)
const {
19076 !Subtarget.allowsUnalignedFPAccess())
19080 if (Subtarget.hasVSX()) {
19081 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19082 VT != MVT::v4f32 && VT != MVT::v4i32)
19089 if (VT == MVT::ppcf128)
19104 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19112 int64_t Imm = ConstNode->getSExtValue();
19133 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19135 switch (Ty->getScalarType()->getTypeID()) {
19140 return Subtarget.hasP9Vector();
19148 if (!
I->hasOneUse())
19152 assert(
User &&
"A single use instruction with no uses.");
19154 switch (
I->getOpcode()) {
19155 case Instruction::FMul: {
19157 if (
User->getOpcode() != Instruction::FSub &&
19158 User->getOpcode() != Instruction::FAdd)
19165 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19166 User->getFastMathFlags().allowContract();
19172 case Instruction::Load: {
19185 if (
User->getOpcode() != Instruction::Store)
19205 static const MCPhysReg ScratchRegs[] = {
19206 PPC::X12, PPC::LR8, PPC::CTR8, 0
19209 return ScratchRegs;
19213 const Constant *PersonalityFn)
const {
19214 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19218 const Constant *PersonalityFn)
const {
19219 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19224 EVT VT ,
unsigned DefinedValues)
const {
19225 if (VT == MVT::v2i64)
19226 return Subtarget.hasDirectMove();
19228 if (Subtarget.hasVSX())
19255 return PPCISD::FNMSUB;
19256 case PPCISD::FNMSUB:
19262 bool LegalOps,
bool OptForSize,
19264 unsigned Depth)
const {
19268 unsigned Opc =
Op.getOpcode();
19269 EVT VT =
Op.getValueType();
19273 case PPCISD::FNMSUB:
19293 if (Flags.hasNoSignedZeros()) {
19297 N0Cost,
Depth + 1);
19301 N1Cost,
Depth + 1);
19303 if (NegN0 && N0Cost <= N1Cost) {
19304 Cost = std::min(N0Cost, N2Cost);
19306 }
else if (NegN1) {
19307 Cost = std::min(N1Cost, N2Cost);
19327 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19333 bool ForCodeSize)
const {
19334 if (!VT.
isSimple() || !Subtarget.hasVSX())
19344 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19349 APSInt IntResult(16,
false);
19354 if (IsExact && IntResult <= 15 && IntResult >= -16)
19356 return Imm.isZero();
19359 return Imm.isPosZero();
19371 unsigned Opcode =
N->getOpcode();
19391 if (Mask->getZExtValue() == OpSizeInBits - 1)
19398 DAGCombinerInfo &DCI)
const {
19399 EVT VT =
N->getValueType(0);
19402 unsigned Opc =
N->getOpcode();
19404 "Unexpected opcode.");
19411 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19415 uint64_t SplatBits = 0;
19416 bool AddSplatCase =
false;
19420 AddSplatCase =
true;
19424 if (!AddSplatCase) {
19428 unsigned SplatBitSize;
19430 APInt APSplatBits, APSplatUndef;
19432 bool BVNIsConstantSplat =
19434 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19435 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19446 if (SplatBits == (EltBits - 1)) {
19450 NewOpc = PPCISD::SHL;
19453 NewOpc = PPCISD::SRL;
19456 NewOpc = PPCISD::SRA;
19460 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19468 if (EltTy != MVT::i64 || SplatBits != 1)
19471 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19474SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19478 if (
N->getValueType(0).isVector())
19479 return combineVectorShift(
N, DCI);
19483 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19486 N->getValueType(0) != MVT::i64)
19501 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19507SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19511 if (
N->getValueType(0).isVector())
19512 return combineVectorShift(
N, DCI);
19517SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19521 if (
N->getValueType(0).isVector())
19522 return combineVectorShift(
N, DCI);
19533 if (!Subtarget.isPPC64())
19539 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19541 Op.getValueType() != MVT::i64)
19545 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19546 Cmp.getOperand(0).getValueType() != MVT::i64)
19550 int64_t NegConstant = 0 -
Constant->getSExtValue();
19559 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19560 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19563 if (LHSHasPattern && !RHSHasPattern)
19565 else if (!LHSHasPattern && !RHSHasPattern)
19569 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19572 SDValue Z = Cmp.getOperand(0);
19574 int64_t NegConstant = 0 -
Constant->getSExtValue();
19587 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19605 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19635 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19638 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19646 if (!GSDN || !ConstNode)
19674 EVT VT =
N->getValueType(0);
19675 if (!Subtarget.hasVSX())
19679 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19691 unsigned NumOfEles =
RHS.getNumOperands();
19692 for (
unsigned i = 0; i < NumOfEles; ++i) {
19694 if (!CN || CN->getSExtValue() != 1)
19709SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19731 DAGCombinerInfo &DCI)
const {
19733 if (Subtarget.useCRBits()) {
19735 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19736 return CRTruncValue;
19743 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19746 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19756 EltToExtract = EltToExtract ? 0 : 1;
19766 return DCI.DAG.getNode(
19768 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19773SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19774 SelectionDAG &DAG = DCI.DAG;
19777 if (!ConstOpOrElement)
19785 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19786 switch (this->Subtarget.getCPUDirective()) {
19809 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19813 EVT VT =
N->getValueType(0);
19818 APInt MulAmtAbs = MulAmt.
abs();
19820 if ((MulAmtAbs - 1).isPowerOf2()) {
19824 if (!IsProfitable(IsNeg,
true, VT))
19837 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19841 if (!IsProfitable(IsNeg,
false, VT))
19862 DAGCombinerInfo &DCI)
const {
19866 SDNodeFlags
Flags =
N->getFlags();
19867 EVT VT =
N->getValueType(0);
19868 SelectionDAG &DAG = DCI.DAG;
19869 unsigned Opc =
N->getOpcode();
19871 bool LegalOps = !DCI.isBeforeLegalizeOps();
19879 if (!
Flags.hasNoSignedZeros())
19895bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19897 if (!Subtarget.is64BitELFABI())
19907 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19912 if (!Callee ||
Callee->isVarArg())
19925bool PPCTargetLowering::
19926isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19931 if (CI->getBitWidth() > 64)
19933 int64_t ConstVal = CI->getZExtValue();
19935 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19944PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19950 if ((Flags & FlagSet) == FlagSet)
19953 if ((Flags & FlagSet) == FlagSet)
19956 if ((Flags & FlagSet) == FlagSet)
19959 if ((Flags & FlagSet) == FlagSet)
19980 if ((FrameIndexAlign % 4) != 0)
19981 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
19982 if ((FrameIndexAlign % 16) != 0)
19983 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
19987 if ((FrameIndexAlign % 4) == 0)
19989 if ((FrameIndexAlign % 16) == 0)
20002 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20003 if ((Imm & 0x3) == 0)
20005 if ((Imm & 0xf) == 0)
20011 const APInt &ConstImm = CN->getAPIntValue();
20030 const APInt &ConstImm = CN->getAPIntValue();
20040 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20051 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20060unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20065 if (!Subtarget.hasP9Vector())
20070 if (Subtarget.hasPrefixInstrs())
20073 if (Subtarget.hasSPE())
20082 unsigned ParentOp = Parent->
getOpcode();
20086 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20087 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20099 if (LSB->isIndexed())
20105 assert(MN &&
"Parent should be a MemSDNode!");
20110 "Not expecting scalar integers larger than 16 bytes!");
20113 else if (
Size == 32)
20120 else if (
Size == 256) {
20121 assert(Subtarget.pairedVectorMemops() &&
20122 "256-bit vectors are only available when paired vector memops is "
20130 else if (MemVT == MVT::f128 || MemVT.
isVector())
20161 FlagSet &= ~PPC::MOF_NoExt;
20166 bool IsNonP1034BitConst =
20170 IsNonP1034BitConst)
20183 int16_t ForceXFormImm = 0;
20186 Disp =
N.getOperand(0);
20187 Base =
N.getOperand(1);
20198 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20199 Disp =
N.getOperand(0);
20200 Base =
N.getOperand(1);
20205 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20214 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20220 if (PartVT == MVT::f64 &&
20221 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20230SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20234 EVT RetVT =
Op.getValueType();
20241 EVT ArgVT =
N.getValueType();
20245 Entry.IsZExt = !Entry.IsSExt;
20246 Args.push_back(Entry);
20254 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20267SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20268 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20270 if (
Op.getValueType() == MVT::f32)
20271 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20273 if (
Op.getValueType() == MVT::f64)
20274 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20279bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20280 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20281 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20285bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20286 return Op.getNode()->getFlags().hasApproximateFuncs();
20289bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20293SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20294 const char *LibCallFloatName,
20295 const char *LibCallDoubleNameFinite,
20296 const char *LibCallFloatNameFinite,
20299 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20302 if (!isLowringToMASSFiniteSafe(
Op))
20303 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20306 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20307 LibCallDoubleNameFinite,
Op, DAG);
20311 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20312 "__xl_powf_finite",
Op, DAG);
20316 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20317 "__xl_sinf_finite",
Op, DAG);
20321 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20322 "__xl_cosf_finite",
Op, DAG);
20326 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20327 "__xl_logf_finite",
Op, DAG);
20331 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20332 "__xl_log10f_finite",
Op, DAG);
20336 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20337 "__xl_expf_finite",
Op, DAG);
20362 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20373 assert(Subtarget.isUsingPCRelativeCalls() &&
20374 "Must be using PC-Relative calls when a valid PC-Relative node is "
20404 Disp =
N.getOperand(1).getOperand(0);
20409 Base =
N.getOperand(0);
20417 EVT CNType = CN->getValueType(0);
20418 uint64_t CNImm = CN->getZExtValue();
20429 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20431 int32_t Addr = (int32_t)CNImm;
20436 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20452 unsigned Opcode =
N.getOpcode();
20460 Base =
N.getOperand(0);
20479 Base = FI ?
N :
N.getOperand(1);
20480 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20491 bool IsVarArg)
const {
20501 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20538 return Intrinsic::ppc_atomicrmw_xchg_i128;
20540 return Intrinsic::ppc_atomicrmw_add_i128;
20542 return Intrinsic::ppc_atomicrmw_sub_i128;
20544 return Intrinsic::ppc_atomicrmw_and_i128;
20546 return Intrinsic::ppc_atomicrmw_or_i128;
20548 return Intrinsic::ppc_atomicrmw_xor_i128;
20550 return Intrinsic::ppc_atomicrmw_nand_i128;
20558 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20560 assert(ValTy->getPrimitiveSizeInBits() == 128);
20562 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20564 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20565 Value *LoHi = Builder.CreateIntrinsic(
20567 {AlignedAddr, IncrLo, IncrHi});
20568 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20569 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20570 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20571 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20572 return Builder.CreateOr(
20573 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20580 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20582 assert(ValTy->getPrimitiveSizeInBits() == 128);
20586 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20588 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20589 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20591 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20594 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20596 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20597 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20598 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20599 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20600 return Builder.CreateOr(
20601 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20605 return Subtarget.useCRBits();
unsigned const MachineRegisterInfo * MRI
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")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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 Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
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.