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");
167 unsigned OpIdx,
bool IsByte,
185 initializeAddrModeMap();
188 bool isPPC64 = Subtarget.isPPC64();
190 const MVT RegVT = Subtarget.getScalarIntVT();
198 if (!Subtarget.hasEFPU2())
215 if (!Subtarget.hasP10Vector()) {
244 if (Subtarget.isISA3_0()) {
277 if (!Subtarget.hasSPE()) {
284 if (Subtarget.useCRBits()) {
287 if (isPPC64 || Subtarget.hasFPCVT()) {
353 if (Subtarget.isISA3_0()) {
388 if (!Subtarget.hasSPE()) {
393 if (Subtarget.hasVSX()) {
398 if (Subtarget.hasFSQRT()) {
403 if (Subtarget.hasFPRND()) {
444 if (Subtarget.hasSPE()) {
454 if (Subtarget.hasSPE())
458 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
461 if (!Subtarget.hasFSQRT() &&
462 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
465 if (Subtarget.hasFCPSGN()) {
473 if (Subtarget.hasFPRND()) {
487 if (Subtarget.isISA3_1()) {
493 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
497 if (Subtarget.isISA3_0()) {
517 if (!Subtarget.useCRBits()) {
530 if (!Subtarget.useCRBits())
533 if (Subtarget.hasFPU()) {
544 if (!Subtarget.useCRBits())
549 if (Subtarget.hasSPE()) {
573 if (Subtarget.hasDirectMove() && isPPC64) {
633 if (Subtarget.is64BitELFABI()) {
644 }
else if (Subtarget.is32BitELFABI()) {
652 if (Subtarget.is32BitELFABI())
668 if (Subtarget.isISA3_0() && isPPC64) {
696 if (Subtarget.hasSPE()) {
718 if (Subtarget.has64BitSupport()) {
733 if (Subtarget.hasLFIWAX() || isPPC64) {
739 if (Subtarget.hasSPE()) {
749 if (Subtarget.hasFPCVT()) {
750 if (Subtarget.has64BitSupport()) {
771 if (Subtarget.use64BitRegs()) {
789 if (Subtarget.has64BitSupport()) {
796 if (Subtarget.hasVSX()) {
809 if (Subtarget.hasAltivec()) {
810 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
827 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
840 if (Subtarget.hasVSX()) {
849 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
859 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
933 if (!Subtarget.hasP8Vector()) {
975 if (Subtarget.hasAltivec())
976 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
979 if (Subtarget.hasP8Altivec())
990 if (Subtarget.hasVSX()) {
996 if (Subtarget.hasP8Altivec())
1001 if (Subtarget.isISA3_1()) {
1047 if (Subtarget.hasVSX()) {
1050 if (Subtarget.hasP8Vector()) {
1054 if (Subtarget.hasDirectMove() && isPPC64) {
1103 if (Subtarget.hasP8Vector())
1112 if (Subtarget.hasP8Altivec()) {
1139 if (Subtarget.isISA3_1())
1242 if (Subtarget.hasP8Altivec()) {
1247 if (Subtarget.hasP9Vector()) {
1252 if (Subtarget.useCRBits()) {
1312 }
else if (Subtarget.hasVSX()) {
1337 for (
MVT VT : {MVT::f32, MVT::f64}) {
1356 if (Subtarget.hasP9Altivec()) {
1357 if (Subtarget.isISA3_1()) {
1380 if (Subtarget.hasP10Vector()) {
1385 if (Subtarget.pairedVectorMemops()) {
1390 if (Subtarget.hasMMA()) {
1391 if (Subtarget.isISAFuture()) {
1407 if (Subtarget.has64BitSupport())
1410 if (Subtarget.isISA3_1())
1428 if (Subtarget.hasAltivec()) {
1446 if (Subtarget.hasFPCVT())
1449 if (Subtarget.useCRBits())
1458 if (Subtarget.useCRBits()) {
1462 if (Subtarget.hasP8Vector())
1467 if (Subtarget.useCRBits()) {
1483 auto CPUDirective = Subtarget.getCPUDirective();
1484 switch (CPUDirective) {
1507 if (Subtarget.enableMachineScheduler())
1581void PPCTargetLowering::initializeAddrModeMap() {
1632 if (MaxAlign == MaxMaxAlign)
1635 if (MaxMaxAlign >= 32 &&
1636 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1637 MaxAlign =
Align(32);
1638 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1640 MaxAlign =
Align(16);
1644 if (EltAlign > MaxAlign)
1645 MaxAlign = EltAlign;
1647 for (
auto *EltTy : STy->elements()) {
1650 if (EltAlign > MaxAlign)
1651 MaxAlign = EltAlign;
1652 if (MaxAlign == MaxMaxAlign)
1665 if (Subtarget.hasAltivec())
1671 return Subtarget.useSoftFloat();
1675 return Subtarget.hasSPE();
1683 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1684 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1688 if (VTy->getScalarType()->isIntegerTy()) {
1690 if (ElemSizeInBits == 32) {
1691 Index = Subtarget.isLittleEndian() ? 2 : 1;
1694 if (ElemSizeInBits == 64) {
1695 Index = Subtarget.isLittleEndian() ? 1 : 0;
1706 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1723 return CFP->getValueAPF().isZero();
1728 return CFP->getValueAPF().isZero();
1736 return Op < 0 ||
Op == Val;
1748 if (ShuffleKind == 0) {
1751 for (
unsigned i = 0; i != 16; ++i)
1754 }
else if (ShuffleKind == 2) {
1757 for (
unsigned i = 0; i != 16; ++i)
1760 }
else if (ShuffleKind == 1) {
1761 unsigned j = IsLE ? 0 : 1;
1762 for (
unsigned i = 0; i != 8; ++i)
1779 if (ShuffleKind == 0) {
1782 for (
unsigned i = 0; i != 16; i += 2)
1786 }
else if (ShuffleKind == 2) {
1789 for (
unsigned i = 0; i != 16; i += 2)
1793 }
else if (ShuffleKind == 1) {
1794 unsigned j = IsLE ? 0 : 2;
1795 for (
unsigned i = 0; i != 8; i += 2)
1816 if (!Subtarget.hasP8Vector())
1820 if (ShuffleKind == 0) {
1823 for (
unsigned i = 0; i != 16; i += 4)
1829 }
else if (ShuffleKind == 2) {
1832 for (
unsigned i = 0; i != 16; i += 4)
1838 }
else if (ShuffleKind == 1) {
1839 unsigned j = IsLE ? 0 : 4;
1840 for (
unsigned i = 0; i != 8; i += 4)
1857 unsigned LHSStart,
unsigned RHSStart) {
1858 if (
N->getValueType(0) != MVT::v16i8)
1860 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1861 "Unsupported merge size!");
1863 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1864 for (
unsigned j = 0; j != UnitSize; ++j) {
1866 LHSStart+j+i*UnitSize) ||
1868 RHSStart+j+i*UnitSize))
1883 if (ShuffleKind == 1)
1885 else if (ShuffleKind == 2)
1890 if (ShuffleKind == 1)
1892 else if (ShuffleKind == 0)
1908 if (ShuffleKind == 1)
1910 else if (ShuffleKind == 2)
1915 if (ShuffleKind == 1)
1917 else if (ShuffleKind == 0)
1967 unsigned RHSStartValue) {
1968 if (
N->getValueType(0) != MVT::v16i8)
1971 for (
unsigned i = 0; i < 2; ++i)
1972 for (
unsigned j = 0; j < 4; ++j)
1974 i*RHSStartValue+j+IndexOffset) ||
1976 i*RHSStartValue+j+IndexOffset+8))
1998 unsigned indexOffset = CheckEven ? 4 : 0;
1999 if (ShuffleKind == 1)
2001 else if (ShuffleKind == 2)
2007 unsigned indexOffset = CheckEven ? 0 : 4;
2008 if (ShuffleKind == 1)
2010 else if (ShuffleKind == 0)
2026 if (
N->getValueType(0) != MVT::v16i8)
2033 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2036 if (i == 16)
return -1;
2041 if (ShiftAmt < i)
return -1;
2046 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2048 for (++i; i != 16; ++i)
2051 }
else if (ShuffleKind == 1) {
2053 for (++i; i != 16; ++i)
2060 ShiftAmt = 16 - ShiftAmt;
2069 EVT VT =
N->getValueType(0);
2070 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2071 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2074 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2078 if (
N->getMaskElt(0) % EltSize != 0)
2083 unsigned ElementBase =
N->getMaskElt(0);
2086 if (ElementBase >= 16)
2091 for (
unsigned i = 1; i != EltSize; ++i)
2092 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2095 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2097 if (
N->getMaskElt(i) < 0) {
2098 for (
unsigned j = 1; j != EltSize; ++j)
2099 if (
N->getMaskElt(i + j) >= 0)
2102 for (
unsigned j = 0; j != EltSize; ++j)
2103 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2120 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2121 "Unexpected element width.");
2122 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2124 unsigned NumOfElem = 16 / Width;
2125 unsigned MaskVal[16];
2126 for (
unsigned i = 0; i < NumOfElem; ++i) {
2127 MaskVal[0] =
N->getMaskElt(i * Width);
2128 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2130 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2134 for (
unsigned int j = 1; j < Width; ++j) {
2135 MaskVal[j] =
N->getMaskElt(i * Width + j);
2136 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2146 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2151 unsigned M0 =
N->getMaskElt(0) / 4;
2152 unsigned M1 =
N->getMaskElt(4) / 4;
2153 unsigned M2 =
N->getMaskElt(8) / 4;
2154 unsigned M3 =
N->getMaskElt(12) / 4;
2155 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2156 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2161 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2162 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2163 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2164 InsertAtByte = IsLE ? 12 : 0;
2169 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2170 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2171 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2172 InsertAtByte = IsLE ? 8 : 4;
2177 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2178 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2179 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2180 InsertAtByte = IsLE ? 4 : 8;
2185 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2186 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2187 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2188 InsertAtByte = IsLE ? 0 : 12;
2195 if (
N->getOperand(1).isUndef()) {
2198 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2199 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2200 InsertAtByte = IsLE ? 12 : 0;
2203 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2204 InsertAtByte = IsLE ? 8 : 4;
2207 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2208 InsertAtByte = IsLE ? 4 : 8;
2211 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2212 InsertAtByte = IsLE ? 0 : 12;
2221 bool &Swap,
bool IsLE) {
2222 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2228 unsigned M0 =
N->getMaskElt(0) / 4;
2229 unsigned M1 =
N->getMaskElt(4) / 4;
2230 unsigned M2 =
N->getMaskElt(8) / 4;
2231 unsigned M3 =
N->getMaskElt(12) / 4;
2235 if (
N->getOperand(1).isUndef()) {
2236 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2237 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2240 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2246 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2250 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2255 ShiftElts = (8 -
M0) % 8;
2256 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2261 ShiftElts = (4 -
M0) % 4;
2266 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2271 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2283 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2288 for (
int i = 0; i < 16; i += Width)
2289 if (
N->getMaskElt(i) != i + Width - 1)
2320 bool &Swap,
bool IsLE) {
2321 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2327 unsigned M0 =
N->getMaskElt(0) / 8;
2328 unsigned M1 =
N->getMaskElt(8) / 8;
2329 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2333 if (
N->getOperand(1).isUndef()) {
2334 if ((
M0 |
M1) < 2) {
2335 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2343 if (
M0 > 1 &&
M1 < 2) {
2353 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2358 }
else if (
M0 > 1 &&
M1 < 2) {
2366 DM = (
M0 << 1) + (
M1 & 1);
2381 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2386 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2402 unsigned EltSize = 16/
N->getNumOperands();
2403 if (EltSize < ByteSize) {
2404 unsigned Multiple = ByteSize/EltSize;
2406 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2409 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2410 if (
N->getOperand(i).isUndef())
continue;
2414 if (!UniquedVals[i&(Multiple-1)].
getNode())
2415 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2416 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2426 bool LeadingZero =
true;
2427 bool LeadingOnes =
true;
2428 for (
unsigned i = 0; i != Multiple-1; ++i) {
2429 if (!UniquedVals[i].
getNode())
continue;
2436 if (!UniquedVals[Multiple-1].
getNode())
2443 if (!UniquedVals[Multiple-1].
getNode())
2454 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2455 if (
N->getOperand(i).isUndef())
continue;
2457 OpVal =
N->getOperand(i);
2458 else if (OpVal !=
N->getOperand(i))
2464 unsigned ValSizeInBytes = EltSize;
2467 Value = CN->getZExtValue();
2469 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2476 if (ValSizeInBytes < ByteSize)
return SDValue();
2487 if (MaskVal == 0)
return SDValue();
2507 Imm = (int16_t)
N->getAsZExtVal();
2508 if (
N->getValueType(0) == MVT::i32)
2509 return Imm == (int32_t)
N->getAsZExtVal();
2511 return Imm == (int64_t)
N->getAsZExtVal();
2529 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2537 for (
SDNode *U :
N->users()) {
2539 if (Memop->getMemoryVT() == MVT::f64) {
2540 Base =
N.getOperand(0);
2541 Index =
N.getOperand(1);
2584 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2586 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2589 Base =
N.getOperand(0);
2590 Index =
N.getOperand(1);
2592 }
else if (
N.getOpcode() ==
ISD::OR) {
2594 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2606 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2607 Base =
N.getOperand(0);
2608 Index =
N.getOperand(1);
2678 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2684 Base =
N.getOperand(0);
2687 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2689 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2690 "Cannot handle constant offsets yet!");
2691 Disp =
N.getOperand(1).getOperand(0);
2696 Base =
N.getOperand(0);
2699 }
else if (
N.getOpcode() ==
ISD::OR) {
2702 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2716 Base =
N.getOperand(0);
2729 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2732 CN->getValueType(0));
2737 if ((CN->getValueType(0) == MVT::i32 ||
2738 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2739 (!EncodingAlignment ||
2740 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2741 int Addr = (int)CN->getZExtValue();
2748 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2769 if (
N.getValueType() != MVT::i64)
2782 Base =
N.getOperand(0);
2798 Base =
N.getOperand(0);
2831 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2832 Base =
N.getOperand(0);
2833 Index =
N.getOperand(1);
2855 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2876 EVT MemVT = LD->getMemoryVT();
2883 if (!ST.hasP8Vector())
2888 if (!ST.hasP9Vector())
2900 if (
Use.getResNo() == 0 &&
2902 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2922 Ptr = LD->getBasePtr();
2923 VT = LD->getMemoryVT();
2924 Alignment = LD->getAlign();
2926 Ptr = ST->getBasePtr();
2927 VT = ST->getMemoryVT();
2928 Alignment = ST->getAlign();
2967 if (VT != MVT::i64) {
2972 if (Alignment <
Align(4))
2982 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
2999 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3041 EVT VT = Subtarget.getScalarIntVT();
3043 : Subtarget.isAIXABI()
3048 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3055 EVT PtrVT =
Op.getValueType();
3061 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3062 if (Subtarget.isUsingPCRelativeCalls()) {
3067 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3071 return getTOCEntry(DAG, SDLoc(CP), GA);
3074 unsigned MOHiFlag, MOLoFlag;
3078 if (IsPIC && Subtarget.isSVR4ABI()) {
3081 return getTOCEntry(DAG, SDLoc(CP), GA);
3104 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3111 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3128 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3141 EVT PtrVT =
Op.getValueType();
3159 return getTOCEntry(DAG,
SDLoc(JT), GA);
3162 unsigned MOHiFlag, MOLoFlag;
3166 if (IsPIC && Subtarget.isSVR4ABI()) {
3169 return getTOCEntry(DAG, SDLoc(GA), GA);
3179 EVT PtrVT =
Op.getValueType();
3184 if (Subtarget.isUsingPCRelativeCalls()) {
3195 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3198 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3207 unsigned MOHiFlag, MOLoFlag;
3217 if (Subtarget.isAIXABI())
3218 return LowerGlobalTLSAddressAIX(
Op, DAG);
3220 return LowerGlobalTLSAddressLinux(
Op, DAG);
3242 if (
I.getOpcode() == Instruction::Call)
3244 if (
Function *CF = CI->getCalledFunction())
3245 if (CF->isDeclaration() &&
3246 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3254 unsigned TLSGVCnt = TLSGV.
size();
3264 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3277 const GlobalValue *GV = GA->
getGlobal();
3279 bool Is64Bit = Subtarget.isPPC64();
3283 if (Subtarget.hasAIXShLibTLSModelOpt())
3293 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3294 bool HasAIXSmallTLSGlobalAttr =
false;
3297 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3301 if (GVar->hasAttribute(
"aix-small-tls"))
3302 HasAIXSmallTLSGlobalAttr =
true;
3321 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3322 IsTLSLocalExecModel) {
3327 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3337 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3342 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3344 "currently only supported on AIX (64-bit mode).");
3346 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3350 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3354 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3356 "currently only supported on AIX (64-bit mode).");
3364 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3367 GlobalVariable *TLSGV =
3371 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3374 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3376 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3385 if (HasAIXSmallLocalDynamicTLS) {
3390 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3394 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3407 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3408 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3409 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3424 const GlobalValue *GV = GA->
getGlobal();
3426 bool is64bit = Subtarget.isPPC64();
3434 if (Subtarget.isUsingPCRelativeCalls()) {
3439 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3440 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3451 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3455 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3462 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3464 MachinePointerInfo());
3471 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3473 if (!TM.isPositionIndependent())
3474 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3480 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3482 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3486 if (Subtarget.isUsingPCRelativeCalls()) {
3489 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3497 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3505 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3510 if (Subtarget.isUsingPCRelativeCalls()) {
3514 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3515 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3523 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3532 PtrVT, GOTPtr, TGA, TGA);
3534 PtrVT, TLSAddr, TGA);
3535 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3543 EVT PtrVT =
Op.getValueType();
3546 const GlobalValue *GV = GSDN->
getGlobal();
3550 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3551 if (Subtarget.isUsingPCRelativeCalls()) {
3558 MachinePointerInfo());
3563 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3568 return getTOCEntry(DAG,
DL, GA);
3571 unsigned MOHiFlag, MOLoFlag;
3575 if (IsPIC && Subtarget.isSVR4ABI()) {
3579 return getTOCEntry(DAG,
DL, GA);
3591 bool IsStrict =
Op->isStrictFPOpcode();
3597 EVT LHSVT =
LHS.getValueType();
3601 if (LHSVT == MVT::f128) {
3602 assert(!Subtarget.hasP9Vector() &&
3603 "SETCC for f128 is already legal under Power9!");
3614 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3616 if (
Op.getValueType() == MVT::v2i64) {
3619 if (
LHS.getValueType() == MVT::v2i64) {
3627 int ShuffV[] = {1, 0, 3, 2};
3632 dl, MVT::v4i32, Shuff, SetCC32));
3649 if (
C->isAllOnes() ||
C->isZero())
3659 EVT VT =
Op.getValueType();
3667 SDNode *
Node =
Op.getNode();
3668 EVT VT =
Node->getValueType(0);
3675 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3679 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3682 if (VT == MVT::i64) {
3701 FprPtr, MachinePointerInfo(SV), MVT::i8);
3712 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3713 InChain = OverflowArea.
getValue(1);
3716 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3746 MachinePointerInfo(SV), MVT::i8);
3759 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3760 MachinePointerInfo(), MVT::i32);
3762 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3766 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3772 false,
true,
nullptr, std::nullopt,
3773 MachinePointerInfo(), MachinePointerInfo());
3778 return Op.getOperand(0);
3783 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3787 "Expecting Inline ASM node.");
3797 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3802 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3803 unsigned NumVals =
Flags.getNumOperandRegisters();
3806 switch (
Flags.getKind()) {
3817 for (; NumVals; --NumVals, ++i) {
3819 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3842 if (Subtarget.isAIXABI()) {
3846 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3847 MaybeAlign PointerAlign(PointerSize);
3848 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3851 : MachineMemOperand::MONone;
3858 const Value *TrampolineAddr =
3868 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3869 PointerAlign, MMOFlags);
3871 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3872 MachinePointerInfo(TrampolineAddr, 0));
3876 SDValue TOCFromDescriptorPtr =
3878 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3879 MachinePointerInfo(Func, TOCPointerOffset),
3880 PointerAlign, MMOFlags);
3881 SDValue TrampolineTOCPointer =
3885 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3886 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3892 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3893 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3900 bool isPPC64 = (PtrVT == MVT::i64);
3904 Args.emplace_back(Trmp, IntPtrTy);
3907 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3909 Args.emplace_back(FPtr, IntPtrTy);
3910 Args.emplace_back(Nest, IntPtrTy);
3913 TargetLowering::CallLoweringInfo CLI(DAG);
3914 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3918 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3919 return CallResult.second;
3924 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3929 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3934 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3935 MachinePointerInfo(SV));
3969 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3972 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3975 uint64_t FPROffset = 1;
3983 MachinePointerInfo(SV), MVT::i8);
3984 uint64_t nextOffset = FPROffset;
3991 MachinePointerInfo(SV, nextOffset), MVT::i8);
3992 nextOffset += StackOffset;
3993 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3996 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3997 MachinePointerInfo(SV, nextOffset));
3998 nextOffset += FrameOffset;
3999 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4002 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4003 MachinePointerInfo(SV, nextOffset));
4008static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4009 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4010 PPC::F11, PPC::F12, PPC::F13};
4015 unsigned PtrByteSize) {
4017 if (Flags.isByVal())
4018 ArgSize = Flags.getByValSize();
4022 if (!Flags.isInConsecutiveRegs())
4023 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4032 unsigned PtrByteSize) {
4033 Align Alignment(PtrByteSize);
4036 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4037 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4038 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4039 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4040 Alignment =
Align(16);
4043 if (Flags.isByVal()) {
4044 auto BVAlign = Flags.getNonZeroByValAlign();
4045 if (BVAlign > PtrByteSize) {
4046 if (BVAlign.value() % PtrByteSize != 0)
4048 "ByVal alignment is not a multiple of the pointer size");
4050 Alignment = BVAlign;
4055 if (Flags.isInConsecutiveRegs()) {
4059 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4073 unsigned PtrByteSize,
unsigned LinkageSize,
4074 unsigned ParamAreaSize,
unsigned &ArgOffset,
4075 unsigned &AvailableFPRs,
4076 unsigned &AvailableVRs) {
4077 bool UseMemory =
false;
4082 ArgOffset =
alignTo(ArgOffset, Alignment);
4085 if (ArgOffset >= LinkageSize + ParamAreaSize)
4090 if (Flags.isInConsecutiveRegsLast())
4091 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4094 if (ArgOffset > LinkageSize + ParamAreaSize)
4099 if (!Flags.isByVal()) {
4100 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4101 if (AvailableFPRs > 0) {
4105 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4106 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4107 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4108 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4109 if (AvailableVRs > 0) {
4121 unsigned NumBytes) {
4125SDValue PPCTargetLowering::LowerFormalArguments(
4129 if (Subtarget.isAIXABI())
4130 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4132 if (Subtarget.is64BitELFABI())
4133 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4135 assert(Subtarget.is32BitELFABI());
4136 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4140SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4176 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4182 const Align PtrAlign(4);
4190 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4191 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4194 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4195 CCValAssign &VA = ArgLocs[i];
4199 const TargetRegisterClass *RC;
4207 RC = &PPC::GPRCRegClass;
4210 if (Subtarget.hasP8Vector())
4211 RC = &PPC::VSSRCRegClass;
4212 else if (Subtarget.hasSPE())
4213 RC = &PPC::GPRCRegClass;
4215 RC = &PPC::F4RCRegClass;
4218 if (Subtarget.hasVSX())
4219 RC = &PPC::VSFRCRegClass;
4220 else if (Subtarget.hasSPE())
4222 RC = &PPC::GPRCRegClass;
4224 RC = &PPC::F8RCRegClass;
4229 RC = &PPC::VRRCRegClass;
4232 RC = &PPC::VRRCRegClass;
4236 RC = &PPC::VRRCRegClass;
4243 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4244 assert(i + 1 < e &&
"No second half of double precision argument");
4249 if (!Subtarget.isLittleEndian())
4251 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4256 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4257 if (ValVT == MVT::i1)
4272 ArgOffset += ArgSize - ObjSize;
4290 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4295 unsigned MinReservedArea = CCByValInfo.getStackSize();
4296 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4312 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4313 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4315 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4318 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4321 unsigned NumFPArgRegs = std::size(FPArgRegs);
4330 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4331 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4334 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4347 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4362 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4366 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4379 if (!MemOps.
empty())
4390 const SDLoc &dl)
const {
4394 else if (
Flags.isZExt())
4401SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4407 bool isELFv2ABI = Subtarget.isELFv2ABI();
4408 bool isLittleEndian = Subtarget.isLittleEndian();
4411 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4414 "fastcc not supported on varargs functions");
4420 unsigned PtrByteSize = 8;
4421 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4424 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4425 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4428 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4429 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4432 const unsigned Num_GPR_Regs = std::size(GPR);
4434 const unsigned Num_VR_Regs = std::size(VR);
4442 bool HasParameterArea = !isELFv2ABI || isVarArg;
4443 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4444 unsigned NumBytes = LinkageSize;
4445 unsigned AvailableFPRs = Num_FPR_Regs;
4446 unsigned AvailableVRs = Num_VR_Regs;
4447 for (
const ISD::InputArg &In : Ins) {
4448 if (
In.Flags.isNest())
4452 LinkageSize, ParamAreaSize, NumBytes,
4453 AvailableFPRs, AvailableVRs))
4454 HasParameterArea =
true;
4461 unsigned ArgOffset = LinkageSize;
4462 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4465 unsigned CurArgIdx = 0;
4466 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4468 bool needsLoad =
false;
4469 EVT ObjectVT = Ins[ArgNo].VT;
4470 EVT OrigVT = Ins[ArgNo].ArgVT;
4472 unsigned ArgSize = ObjSize;
4473 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4474 if (Ins[ArgNo].isOrigArg()) {
4475 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4476 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4481 unsigned CurArgOffset;
4483 auto ComputeArgOffset = [&]() {
4487 ArgOffset =
alignTo(ArgOffset, Alignment);
4488 CurArgOffset = ArgOffset;
4495 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4496 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4501 if (
Flags.isByVal()) {
4502 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4508 ObjSize =
Flags.getByValSize();
4509 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4531 if (HasParameterArea ||
4532 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4539 if (ObjSize < PtrByteSize) {
4543 if (!isLittleEndian) {
4549 if (GPR_idx != Num_GPR_Regs) {
4556 MachinePointerInfo(&*FuncArg), ObjType);
4561 ArgOffset += PtrByteSize;
4570 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4571 if (GPR_idx == Num_GPR_Regs)
4582 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4586 MachinePointerInfo(&*FuncArg, j), ObjType);
4590 ArgOffset += ArgSize;
4599 if (
Flags.isNest()) {
4604 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4605 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4613 if (GPR_idx != Num_GPR_Regs) {
4618 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4621 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4627 ArgSize = PtrByteSize;
4638 if (FPR_idx != Num_FPR_Regs) {
4641 if (ObjectVT == MVT::f32)
4643 Subtarget.hasP8Vector()
4644 ? &PPC::VSSRCRegClass
4645 : &PPC::F4RCRegClass);
4648 ? &PPC::VSFRCRegClass
4649 : &PPC::F8RCRegClass);
4664 if (ObjectVT == MVT::f32) {
4665 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4683 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4684 ArgOffset += ArgSize;
4685 if (
Flags.isInConsecutiveRegsLast())
4686 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4700 if (VR_idx != Num_VR_Regs) {
4717 if (ObjSize < ArgSize && !isLittleEndian)
4718 CurArgOffset += ArgSize - ObjSize;
4721 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4728 unsigned MinReservedArea;
4729 if (HasParameterArea)
4730 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4732 MinReservedArea = LinkageSize;
4749 int Depth = ArgOffset;
4758 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4759 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4771 if (!MemOps.
empty())
4780 unsigned ParamSize) {
4782 if (!isTailCall)
return 0;
4786 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4788 if (SPDiff < FI->getTailCallSPDelta())
4804 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4863 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4866 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4878 const unsigned PtrByteSize = 8;
4882 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4883 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4886 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4887 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4890 const unsigned NumGPRs = std::size(GPR);
4891 const unsigned NumFPRs = 13;
4892 const unsigned NumVRs = std::size(VR);
4893 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4895 unsigned NumBytes = LinkageSize;
4896 unsigned AvailableFPRs = NumFPRs;
4897 unsigned AvailableVRs = NumVRs;
4900 if (Param.Flags.isNest())
continue;
4903 LinkageSize, ParamAreaSize, NumBytes,
4904 AvailableFPRs, AvailableVRs))
4915 auto CalleeArgEnd = CB.
arg_end();
4918 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4919 const Value* CalleeArg = *CalleeArgIter;
4920 const Value* CallerArg = &(*CallerArgIter);
4921 if (CalleeArg == CallerArg)
4947 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4957bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4962 bool isCalleeExternalSymbol)
const {
4965 if (
DisableSCO && !TailCallOpt)
return false;
4968 if (isVarArg)
return false;
4975 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5011 if (!Subtarget.isUsingPCRelativeCalls() &&
5016 if (!Subtarget.isUsingPCRelativeCalls() &&
5044bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5057 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5078 if (!
C)
return nullptr;
5080 int Addr =
C->getZExtValue();
5081 if ((Addr & 3) != 0 ||
5087 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5094struct TailCallArgumentInfo {
5099 TailCallArgumentInfo() =
default;
5109 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5110 SDValue Arg = TailCallArgs[i].Arg;
5111 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5112 int FI = TailCallArgs[i].FrameIdx;
5115 Chain, dl, Arg, FIN,
5124 int SPDiff,
const SDLoc &dl) {
5130 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5131 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5133 NewRetAddrLoc,
true);
5136 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5146 int SPDiff,
unsigned ArgOffset,
5148 int Offset = ArgOffset + SPDiff;
5151 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5153 TailCallArgumentInfo Info;
5155 Info.FrameIdxOp = FIN;
5163SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5168 LROpOut = getReturnAddrFrameIndex(DAG);
5169 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5170 MachinePointerInfo());
5187 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5195 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5219 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5229 if (!MemOpChains2.
empty())
5253SDValue PPCTargetLowering::LowerCallResult(
5261 CCRetInfo.AnalyzeCallResult(
5267 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5268 CCValAssign &VA = RVLocs[i];
5273 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5283 if (!Subtarget.isLittleEndian())
5285 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5351 bool IsStrictFPCall =
false) {
5353 return PPCISD::TC_RETURN;
5355 unsigned RetOpc = 0;
5366 if (Subtarget.usePointerGlueHelper())
5367 RetOpc = PPCISD::BL_LOAD_TOC;
5373 RetOpc = PPCISD::CALL_NOTOC;
5388 RetOpc = PPCISD::CALL;
5389 if (IsStrictFPCall) {
5393 case PPCISD::BCTRL_LOAD_TOC:
5394 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5397 RetOpc = PPCISD::BCTRL_RM;
5399 case PPCISD::BL_LOAD_TOC:
5400 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5402 case PPCISD::CALL_NOTOC:
5403 RetOpc = PPCISD::CALL_NOTOC_RM;
5406 RetOpc = PPCISD::CALL_RM;
5408 case PPCISD::CALL_NOP:
5409 RetOpc = PPCISD::CALL_NOP_RM;
5423 auto isLocalCallee = [&]() {
5439 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5455 return getAIXFuncEntryPointSymbolSDNode(GV);
5462 const char *SymName = S->getSymbol();
5469 return getAIXFuncEntryPointSymbolSDNode(
F);
5475 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5483 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5490 assert(Callee.getNode() &&
"What no callee?");
5496 "Expected a CALLSEQ_STARTSDNode.");
5513 SDValue MTCTROps[] = {Chain, Callee, Glue};
5514 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5515 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5555 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5574 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5575 Alignment, MMOFlags);
5582 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5589 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5601 "Nest parameter is not supported on AIX.");
5616 const SDLoc &dl,
bool hasNest,
5626 Chain = MoveToPhysicalReg.
getValue(0);
5627 Glue = MoveToPhysicalReg.
getValue(1);
5634 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5637 const bool IsPPC64 = Subtarget.isPPC64();
5642 Ops.push_back(Chain);
5646 Ops.push_back(Callee);
5647 else if (Subtarget.usePointerGlueHelper()) {
5648 Ops.push_back(Callee);
5671 Ops.push_back(AddTOC);
5682 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5691 for (
const auto &[
Reg,
N] : RegsToPass)
5709 assert(Mask &&
"Missing call preserved mask for calling convention");
5714 Ops.push_back(Glue);
5717SDValue PPCTargetLowering::FinishCall(
5724 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5725 Subtarget.isAIXABI())
5732 if (!CFlags.IsIndirect)
5734 else if (Subtarget.usesFunctionDescriptors()) {
5735 if (Subtarget.usePointerGlueHelper()) {
5737 CFlags.HasNest, Subtarget);
5743 dl, CFlags.HasNest, Subtarget);
5755 if (CFlags.IsTailCall) {
5763 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5764 "Expecting a global address, external symbol, absolute value, "
5765 "register or an indirect tail call when PC Relative calls are "
5768 assert(CallOpc == PPCISD::TC_RETURN &&
5769 "Unexpected call opcode for a tail call.");
5776 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5777 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5789 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5792 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5812 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5813 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5817bool PPCTargetLowering::isEligibleForTCO(
5822 bool isCalleeExternalSymbol)
const {
5826 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5827 return IsEligibleForTailCallOptimization_64SVR4(
5828 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5829 isCalleeExternalSymbol);
5831 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5859 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5874 "Callee should be an llvm::Function object.");
5877 <<
"\nTCO callee: ");
5884 "site marked musttail");
5891 Callee = LowerGlobalAddress(Callee, DAG);
5894 CallConv, isTailCall, isVarArg, isPatchPoint,
5897 Subtarget.is64BitELFABI() &&
5901 if (Subtarget.isAIXABI())
5902 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5905 assert(Subtarget.isSVR4ABI());
5906 if (Subtarget.isPPC64())
5907 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5909 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5913SDValue PPCTargetLowering::LowerCall_32SVR4(
5924 const bool IsVarArg = CFlags.IsVarArg;
5925 const bool IsTailCall = CFlags.IsTailCall;
5931 const Align PtrAlign(4);
5942 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5950 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5953 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5960 unsigned NumArgs = Outs.
size();
5962 for (
unsigned i = 0; i != NumArgs; ++i) {
5963 MVT ArgVT = Outs[i].VT;
5964 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5969 Outs[i].OrigTy, CCInfo);
5972 ArgFlags, Outs[i].OrigTy, CCInfo);
5977 errs() <<
"Call operand #" << i <<
" has unhandled type "
5990 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
5993 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6000 unsigned NumBytes = CCByValInfo.getStackSize();
6014 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6025 bool seenFloatArg =
false;
6030 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6032 ++i, ++RealArgIdx) {
6033 CCValAssign &VA = ArgLocs[i];
6034 SDValue Arg = OutVals[RealArgIdx];
6035 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6037 if (
Flags.isByVal()) {
6042 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6043 CCValAssign &ByValVA = ByValArgLocs[
j++];
6065 Chain = CallSeqStart = NewCallSeqStart;
6084 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6085 bool IsLE = Subtarget.isLittleEndian();
6086 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6089 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6091 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6106 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6115 if (!MemOpChains.
empty())
6121 for (
const auto &[
Reg,
N] : RegsToPass) {
6129 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6132 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6142 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6143 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6148SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6160 return NewCallSeqStart;
6163SDValue PPCTargetLowering::LowerCall_64SVR4(
6170 bool isELFv2ABI = Subtarget.isELFv2ABI();
6171 bool isLittleEndian = Subtarget.isLittleEndian();
6173 bool IsSibCall =
false;
6177 unsigned PtrByteSize = 8;
6190 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6192 assert(!(IsFastCall && CFlags.IsVarArg) &&
6193 "fastcc not supported on varargs functions");
6199 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6200 unsigned NumBytes = LinkageSize;
6201 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6204 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6205 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6208 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6209 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6212 const unsigned NumGPRs = std::size(GPR);
6214 const unsigned NumVRs = std::size(VR);
6220 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6221 if (!HasParameterArea) {
6222 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6223 unsigned AvailableFPRs = NumFPRs;
6224 unsigned AvailableVRs = NumVRs;
6225 unsigned NumBytesTmp = NumBytes;
6226 for (
unsigned i = 0; i !=
NumOps; ++i) {
6227 if (Outs[i].
Flags.isNest())
continue;
6229 PtrByteSize, LinkageSize, ParamAreaSize,
6230 NumBytesTmp, AvailableFPRs, AvailableVRs))
6231 HasParameterArea =
true;
6237 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6242 HasParameterArea =
false;
6245 for (
unsigned i = 0; i !=
NumOps; ++i) {
6246 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6247 EVT ArgVT = Outs[i].VT;
6248 EVT OrigVT = Outs[i].ArgVT;
6254 if (
Flags.isByVal()) {
6255 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6256 if (NumGPRsUsed > NumGPRs)
6257 HasParameterArea =
true;
6264 if (++NumGPRsUsed <= NumGPRs)
6274 if (++NumVRsUsed <= NumVRs)
6278 if (++NumVRsUsed <= NumVRs)
6283 if (++NumFPRsUsed <= NumFPRs)
6287 HasParameterArea =
true;
6294 NumBytes =
alignTo(NumBytes, Alignement);
6297 if (
Flags.isInConsecutiveRegsLast())
6298 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6301 unsigned NumBytesActuallyUsed = NumBytes;
6311 if (HasParameterArea)
6312 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6314 NumBytes = LinkageSize;
6329 if (CFlags.IsTailCall)
6341 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6352 unsigned ArgOffset = LinkageSize;
6358 for (
unsigned i = 0; i !=
NumOps; ++i) {
6360 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6361 EVT ArgVT = Outs[i].VT;
6362 EVT OrigVT = Outs[i].ArgVT;
6371 auto ComputePtrOff = [&]() {
6375 ArgOffset =
alignTo(ArgOffset, Alignment);
6386 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6387 GPR_idx = std::min(GPR_idx, NumGPRs);
6394 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6400 if (
Flags.isByVal()) {
6418 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6419 if (GPR_idx != NumGPRs) {
6421 MachinePointerInfo(), VT);
6423 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6425 ArgOffset += PtrByteSize;
6430 if (GPR_idx == NumGPRs &&
Size < 8) {
6432 if (!isLittleEndian) {
6437 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6440 ArgOffset += PtrByteSize;
6449 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6450 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6455 if (
Size < 8 && GPR_idx != NumGPRs) {
6465 if (!isLittleEndian) {
6469 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6475 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6477 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6480 ArgOffset += PtrByteSize;
6486 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6489 if (GPR_idx != NumGPRs) {
6490 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6493 MachinePointerInfo(), ObjType);
6496 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6497 ArgOffset += PtrByteSize;
6499 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6511 if (
Flags.isNest()) {
6513 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6520 if (GPR_idx != NumGPRs) {
6521 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6526 assert(HasParameterArea &&
6527 "Parameter area must exist to pass an argument in memory.");
6529 true, CFlags.IsTailCall,
false, MemOpChains,
6530 TailCallArguments, dl);
6532 ArgOffset += PtrByteSize;
6535 ArgOffset += PtrByteSize;
6548 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6549 bool NeededLoad =
false;
6552 if (FPR_idx != NumFPRs)
6553 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6556 if (!NeedGPROrStack)
6558 else if (GPR_idx != NumGPRs && !IsFastCall) {
6572 }
else if (!
Flags.isInConsecutiveRegs()) {
6578 }
else if (ArgOffset % PtrByteSize != 0) {
6582 if (!isLittleEndian)
6587 }
else if (
Flags.isInConsecutiveRegsLast()) {
6590 if (!isLittleEndian)
6600 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6608 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6613 assert(HasParameterArea &&
6614 "Parameter area must exist to pass an argument in memory.");
6616 true, CFlags.IsTailCall,
false, MemOpChains,
6617 TailCallArguments, dl);
6624 if (!IsFastCall || NeededLoad) {
6626 Flags.isInConsecutiveRegs()) ? 4 : 8;
6627 if (
Flags.isInConsecutiveRegsLast())
6628 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6648 if (CFlags.IsVarArg) {
6649 assert(HasParameterArea &&
6650 "Parameter area must exist if we have a varargs call.");
6654 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6656 if (VR_idx != NumVRs) {
6658 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6660 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6663 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6664 if (GPR_idx == NumGPRs)
6669 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6671 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6677 if (VR_idx != NumVRs) {
6678 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6683 assert(HasParameterArea &&
6684 "Parameter area must exist to pass an argument in memory.");
6686 true, CFlags.IsTailCall,
true, MemOpChains,
6687 TailCallArguments, dl);
6698 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6699 "mismatch in size of parameter area");
6700 (void)NumBytesActuallyUsed;
6702 if (!MemOpChains.
empty())
6708 if (CFlags.IsIndirect) {
6712 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6717 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6727 if (isELFv2ABI && !CFlags.IsPatchPoint)
6728 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6734 for (
const auto &[
Reg,
N] : RegsToPass) {
6739 if (CFlags.IsTailCall && !IsSibCall)
6743 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6744 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6751 "Required alignment greater than stack alignment.");
6771 return RequiredAlign <= 8;
6776 return RequiredAlign <= 4;
6784 State.getMachineFunction().getSubtarget());
6785 const bool IsPPC64 = Subtarget.isPPC64();
6786 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6787 const Align PtrAlign(PtrSize);
6788 const Align StackAlign(16);
6791 if (ValVT == MVT::f128)
6795 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6796 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6798 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6799 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6802 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6803 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6804 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6809 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6818 if (ByValAlign > StackAlign)
6820 "16 are not supported.");
6823 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6827 if (ByValSize == 0) {
6829 State.getStackSize(), RegVT, LocInfo));
6834 unsigned NextReg = State.getFirstUnallocated(GPRs);
6835 while (NextReg != GPRs.
size() &&
6840 State.AllocateStack(PtrSize, PtrAlign);
6841 assert(
Reg &&
"Alocating register unexpectedly failed.");
6843 NextReg = State.getFirstUnallocated(GPRs);
6846 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6847 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6867 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6871 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6890 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6896 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6898 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6899 if (State.isVarArg()) {
6931 const unsigned VecSize = 16;
6932 const Align VecAlign(VecSize);
6934 if (!State.isVarArg()) {
6937 if (
MCRegister VReg = State.AllocateReg(VR)) {
6944 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6949 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6952 while (NextRegIndex != GPRs.
size() &&
6956 State.AllocateStack(PtrSize, PtrAlign);
6957 assert(
Reg &&
"Allocating register unexpectedly failed.");
6959 NextRegIndex = State.getFirstUnallocated(GPRs);
6967 if (
MCRegister VReg = State.AllocateReg(VR)) {
6970 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6971 State.AllocateReg(GPRs);
6972 State.AllocateStack(VecSize, VecAlign);
6976 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6982 if (NextRegIndex == GPRs.
size()) {
6983 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6991 if (GPRs[NextRegIndex] == PPC::R9) {
6992 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6996 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
6997 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
6998 assert(FirstReg && SecondReg &&
6999 "Allocating R9 or R10 unexpectedly failed.");
7010 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7013 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7015 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7030 assert((IsPPC64 || SVT != MVT::i64) &&
7031 "i64 should have been split for 32-bit codegen.");
7039 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7041 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7043 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7051 return &PPC::VRRCRegClass;
7064 else if (Flags.isZExt())
7076 "Reg must be a valid argument register!");
7077 return LASize + 4 * (
Reg - PPC::R3);
7082 "Reg must be a valid argument register!");
7083 return LASize + 8 * (
Reg - PPC::X3);
7129SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7136 "Unexpected calling convention!");
7144 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7146 const bool IsPPC64 = Subtarget.isPPC64();
7147 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7153 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7154 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7158 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7159 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7160 uint64_t SaveStackPos = CCInfo.getStackSize();
7162 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7166 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7167 CCValAssign &VA = ArgLocs[
I++];
7172 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7173 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7185 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7187 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7193 MachinePointerInfo(),
Align(PtrByteSize));
7199 unsigned StoreSize =
7201 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7204 auto HandleMemLoc = [&]() {
7207 assert((ValSize <= LocSize) &&
7208 "Object size is larger than size of MemLoc");
7211 if (LocSize > ValSize)
7212 CurArgOffset += LocSize - ValSize;
7214 const bool IsImmutable =
7220 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7254 assert(isVarArg &&
"Only use custom memloc for vararg.");
7257 const unsigned OriginalValNo = VA.
getValNo();
7258 (void)OriginalValNo;
7260 auto HandleCustomVecRegLoc = [&]() {
7261 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7262 "Missing custom RegLoc.");
7265 "Unexpected Val type for custom RegLoc.");
7267 "ValNo mismatch between custom MemLoc and RegLoc.");
7271 Subtarget.hasVSX()));
7278 HandleCustomVecRegLoc();
7279 HandleCustomVecRegLoc();
7283 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7285 "Only 2 custom RegLocs expected for 64-bit codegen.");
7286 HandleCustomVecRegLoc();
7287 HandleCustomVecRegLoc();
7331 const unsigned Size =
7343 if (
Flags.isByVal()) {
7347 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7349 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7357 const TargetRegisterClass *RegClass =
7358 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7360 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7373 CopyFrom.
getValue(1), dl, CopyFrom,
7383 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7386 "RegLocs should be for ByVal argument.");
7388 const CCValAssign RL = ArgLocs[
I++];
7393 if (
Offset != StackSize) {
7395 "Expected MemLoc for remaining bytes.");
7396 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7410 Subtarget.hasVSX()));
7427 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7429 unsigned CallerReservedArea = std::max<unsigned>(
7430 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7436 CallerReservedArea =
7441 int VAListIndex = 0;
7445 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7446 unsigned FixedStackSize =
7447 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7463 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7464 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7466 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7467 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7468 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7474 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7476 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7479 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7480 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7483 MachinePointerInfo MPI =
7493 if (!MemOps.
empty())
7499SDValue PPCTargetLowering::LowerCall_AIX(
7512 "Unexpected calling convention!");
7514 if (CFlags.IsPatchPoint)
7517 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7521 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7528 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7529 const bool IsPPC64 = Subtarget.isPPC64();
7531 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7532 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7533 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7541 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7542 const unsigned NumBytes = std::max<unsigned>(
7543 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7559 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7560 const unsigned ValNo = ArgLocs[
I].getValNo();
7562 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7564 if (
Flags.isByVal()) {
7565 const unsigned ByValSize =
Flags.getByValSize();
7573 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7579 MachinePointerInfo(), VT);
7582 unsigned LoadOffset = 0;
7585 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7588 LoadOffset += PtrByteSize;
7589 const CCValAssign &ByValVA = ArgLocs[
I++];
7591 "Unexpected location for pass-by-value argument.");
7595 if (LoadOffset == ByValSize)
7599 assert(ArgLocs[
I].getValNo() == ValNo &&
7600 "Expected additional location for by-value argument.");
7602 if (ArgLocs[
I].isMemLoc()) {
7603 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7604 const CCValAssign &ByValVA = ArgLocs[
I++];
7605 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7608 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7614 CallSeqStart, MemcpyFlags, DAG, dl);
7623 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7624 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7625 "Unexpected register residue for by-value argument.");
7627 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7631 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7641 "Unexpected load emitted during handling of pass-by-value "
7649 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7654 const CCValAssign &ByValVA = ArgLocs[
I++];
7659 CCValAssign &VA = ArgLocs[
I++];
7684 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7690 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7692 const unsigned OriginalValNo = VA.
getValNo();
7694 unsigned LoadOffset = 0;
7695 auto HandleCustomVecRegLoc = [&]() {
7696 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7697 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7698 "Expected custom RegLoc.");
7699 CCValAssign RegVA = ArgLocs[
I++];
7701 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7707 LoadOffset += PtrByteSize;
7713 HandleCustomVecRegLoc();
7714 HandleCustomVecRegLoc();
7716 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7717 ArgLocs[
I].getValNo() == OriginalValNo) {
7719 "Only 2 custom RegLocs expected for 64-bit codegen.");
7720 HandleCustomVecRegLoc();
7721 HandleCustomVecRegLoc();
7732 DAG.
getStore(Chain, dl, Arg, PtrOff,
7734 Subtarget.getFrameLowering()->getStackAlign()));
7741 "Unexpected register handling for calling convention.");
7747 "Custom register handling only expected for VarArg.");
7752 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7756 else if (Arg.getValueType().getFixedSizeInBits() <
7764 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7765 "Unexpected custom register for argument!");
7766 CCValAssign &GPR1 = VA;
7775 CCValAssign &PeekArg = ArgLocs[
I];
7778 CCValAssign &GPR2 = ArgLocs[
I++];
7786 if (!MemOpChains.
empty())
7791 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7792 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7793 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7794 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7795 const MVT PtrVT = Subtarget.getScalarIntVT();
7796 const unsigned TOCSaveOffset =
7797 Subtarget.getFrameLowering()->getTOCSaveOffset();
7812 for (
auto Reg : RegsToPass) {
7817 const int SPDiff = 0;
7818 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7819 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7827 const Type *RetTy)
const {
7829 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7830 return CCInfo.CheckReturn(
7845 CCInfo.AnalyzeReturn(Outs,
7854 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7855 CCValAssign &VA = RVLocs[i];
7858 SDValue Arg = OutVals[RealResIdx];
7873 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7874 bool isLittleEndian = Subtarget.isLittleEndian();
7877 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7881 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7896 RetOps.push_back(Glue);
7898 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7902PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7907 EVT IntVT =
Op.getValueType();
7911 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7915 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7927 bool isPPC64 = Subtarget.isPPC64();
7928 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7937 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7943 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7948 bool isPPC64 = Subtarget.isPPC64();
7953 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7959 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7969PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7971 bool isPPC64 = Subtarget.isPPC64();
7976 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7982 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8005 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8007 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8009 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8010 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8017 bool isPPC64 = Subtarget.isPPC64();
8027 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8029 Op.getOperand(0),
Op.getOperand(1));
8035 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8036 Op.getOperand(0),
Op.getOperand(1));
8040 if (
Op.getValueType().isVector())
8041 return LowerVectorLoad(
Op, DAG);
8043 assert(
Op.getValueType() == MVT::i1 &&
8044 "Custom lowering only for i1 loads");
8053 MachineMemOperand *MMO =
LD->getMemOperand();
8057 BasePtr, MVT::i8, MMO);
8065 if (
Op.getOperand(1).getValueType().isVector())
8066 return LowerVectorStore(
Op, DAG);
8068 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8069 "Custom lowering only for i1 stores");
8079 MachineMemOperand *MMO =
ST->getMemOperand();
8088 assert(
Op.getValueType() == MVT::i1 &&
8089 "Custom lowering only for i1 results");
8117 EVT TrgVT =
Op.getValueType();
8141 if (SrcSize == 256) {
8152 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8158 SmallVector<int, 16> ShuffV;
8159 if (Subtarget.isLittleEndian())
8160 for (
unsigned i = 0; i < TrgNumElts; ++i)
8163 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8167 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8180 EVT ResVT =
Op.getValueType();
8181 EVT CmpVT =
Op.getOperand(0).getValueType();
8183 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8189 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8202 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8206 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8223 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8236 if (
LHS.getValueType() == MVT::f32)
8238 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8241 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8249 if (
LHS.getValueType() == MVT::f32)
8251 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8258 if (
LHS.getValueType() == MVT::f32)
8260 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8272 if (
Cmp.getValueType() == MVT::f32)
8274 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8277 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8282 if (
Cmp.getValueType() == MVT::f32)
8284 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8288 if (
Cmp.getValueType() == MVT::f32)
8290 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8294 if (
Cmp.getValueType() == MVT::f32)
8296 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8300 if (
Cmp.getValueType() == MVT::f32)
8302 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8311 case PPCISD::FCTIDZ:
8312 return PPCISD::STRICT_FCTIDZ;
8313 case PPCISD::FCTIWZ:
8314 return PPCISD::STRICT_FCTIWZ;
8315 case PPCISD::FCTIDUZ:
8316 return PPCISD::STRICT_FCTIDUZ;
8317 case PPCISD::FCTIWUZ:
8318 return PPCISD::STRICT_FCTIWUZ;
8320 return PPCISD::STRICT_FCFID;
8321 case PPCISD::FCFIDU:
8322 return PPCISD::STRICT_FCFIDU;
8323 case PPCISD::FCFIDS:
8324 return PPCISD::STRICT_FCFIDS;
8325 case PPCISD::FCFIDUS:
8326 return PPCISD::STRICT_FCFIDUS;
8333 bool IsStrict =
Op->isStrictFPOpcode();
8342 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8344 MVT DestTy =
Op.getSimpleValueType();
8345 assert(Src.getValueType().isFloatingPoint() &&
8346 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8347 DestTy == MVT::i64) &&
8348 "Invalid FP_TO_INT types");
8349 if (Src.getValueType() == MVT::f32) {
8353 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8358 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8364 Opc = IsSigned ? PPCISD::FCTIWZ
8365 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8368 assert((IsSigned || Subtarget.hasFPCVT()) &&
8369 "i64 FP_TO_UINT is supported only with FPCVT");
8370 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8372 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8384void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8386 const SDLoc &dl)
const {
8390 bool IsStrict =
Op->isStrictFPOpcode();
8393 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8394 (IsSigned || Subtarget.hasFPCVT());
8397 MachinePointerInfo MPI =
8405 Alignment =
Align(4);
8406 MachineMemOperand *MMO =
8412 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8416 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8417 !Subtarget.isLittleEndian()) {
8426 RLI.Alignment = Alignment;
8434 const SDLoc &dl)
const {
8437 if (
Op->isStrictFPOpcode())
8444 const SDLoc &dl)
const {
8445 bool IsStrict =
Op->isStrictFPOpcode();
8448 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8449 EVT SrcVT = Src.getValueType();
8450 EVT DstVT =
Op.getValueType();
8453 if (SrcVT == MVT::f128)
8454 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8458 if (SrcVT == MVT::ppcf128) {
8459 if (DstVT == MVT::i32) {
8464 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8475 {Op.getOperand(0), Lo, Hi}, Flags);
8478 {Res.getValue(1), Res}, Flags);
8484 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8508 {Chain, Src, FltOfs}, Flags);
8512 {Chain, Val}, Flags);
8515 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8533 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8534 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8537 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8539 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8540 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8551bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8556 if (
Op->isStrictFPOpcode())
8561 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8565 Op.getOperand(0).getValueType())) {
8567 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8572 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8573 LD->isNonTemporal())
8575 if (
LD->getMemoryVT() != MemVT)
8585 RLI.Ptr =
LD->getBasePtr();
8586 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8588 "Non-pre-inc AM on PPC?");
8593 RLI.Chain =
LD->getChain();
8594 RLI.MPI =
LD->getPointerInfo();
8595 RLI.IsDereferenceable =
LD->isDereferenceable();
8596 RLI.IsInvariant =
LD->isInvariant();
8597 RLI.Alignment =
LD->getAlign();
8598 RLI.AAInfo =
LD->getAAInfo();
8599 RLI.Ranges =
LD->getRanges();
8601 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8608bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8609 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8616 if (!Subtarget.hasP9Vector() &&
8620 for (SDUse &Use : Origin->
uses()) {
8623 if (
Use.getResNo() != 0)
8650 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8651 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8652 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8653 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8654 if (
Op->isStrictFPOpcode()) {
8656 Chain =
Op.getOperand(0);
8658 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8660 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8668 const SDLoc &dl)
const {
8669 assert((
Op.getValueType() == MVT::f32 ||
8670 Op.getValueType() == MVT::f64) &&
8671 "Invalid floating point type as target of conversion");
8672 assert(Subtarget.hasFPCVT() &&
8673 "Int to FP conversions with direct moves require FPCVT");
8674 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8675 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8678 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8697 for (
unsigned i = 1; i < NumConcat; ++i)
8704 const SDLoc &dl)
const {
8705 bool IsStrict =
Op->isStrictFPOpcode();
8706 unsigned Opc =
Op.getOpcode();
8707 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8710 "Unexpected conversion type");
8711 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8712 "Supports conversions to v2f64/v4f32 only.");
8716 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8719 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8724 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8726 SmallVector<int, 16> ShuffV;
8727 for (
unsigned i = 0; i < WideNumElts; ++i)
8730 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8731 int SaveElts = FourEltRes ? 4 : 2;
8732 if (Subtarget.isLittleEndian())
8733 for (
int i = 0; i < SaveElts; i++)
8734 ShuffV[i * Stride] = i;
8736 for (
int i = 1; i <= SaveElts; i++)
8737 ShuffV[i * Stride - 1] = i - 1;
8745 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8746 EVT ExtVT = Src.getValueType();
8747 if (Subtarget.hasP9Altivec())
8758 {Op.getOperand(0), Extend}, Flags);
8760 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8768 bool IsStrict =
Op->isStrictFPOpcode();
8769 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8774 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8776 EVT InVT = Src.getValueType();
8777 EVT OutVT =
Op.getValueType();
8780 return LowerINT_TO_FPVector(
Op, DAG, dl);
8783 if (
Op.getValueType() == MVT::f128)
8784 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8787 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8790 if (Src.getValueType() == MVT::i1) {
8802 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8803 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8804 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8806 assert((IsSigned || Subtarget.hasFPCVT()) &&
8807 "UINT_TO_FP is supported only with FPCVT");
8809 if (Src.getValueType() == MVT::i64) {
8824 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8825 !
Op->getFlags().hasApproximateFuncs()) {
8865 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8866 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8867 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8870 }
else if (Subtarget.hasLFIWAX() &&
8871 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8872 MachineMemOperand *MMO =
8874 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8878 Ops, MVT::i32, MMO);
8881 }
else if (Subtarget.hasFPCVT() &&
8882 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8883 MachineMemOperand *MMO =
8885 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8889 Ops, MVT::i32, MMO);
8892 }
else if (((Subtarget.hasLFIWAX() &&
8894 (Subtarget.hasFPCVT() &&
8909 "Expected an i32 store");
8915 RLI.Alignment =
Align(4);
8917 MachineMemOperand *MMO =
8919 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8922 PPCISD::LFIWZX : PPCISD::LFIWAX,
8923 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8924 Ops, MVT::i32, MMO);
8925 Chain =
Bits.getValue(1);
8933 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8937 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8946 assert(Src.getValueType() == MVT::i32 &&
8947 "Unhandled INT_TO_FP type in custom expander!");
8957 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8960 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8970 "Expected an i32 store");
8976 RLI.Alignment =
Align(4);
8979 MachineMemOperand *MMO =
8981 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8987 if (ReusingLoad && RLI.ResChain) {
8991 assert(Subtarget.isPPC64() &&
8992 "i32->FP without LFIWAX supported only on PPC64");
9001 Chain, dl, Ext64, FIdx,
9007 MVT::f64, dl, Chain, FIdx,
9016 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9020 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9037 uint64_t
Mode = CVal->getZExtValue();
9038 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9039 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9040 if (Subtarget.isISA3_0())
9043 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9044 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9047 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9048 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9050 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9068 if (!Subtarget.isISA3_0()) {
9069 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9073 if (Subtarget.isPPC64()) {
9074 if (Subtarget.isISA3_0()) {
9079 PPC::RLDIMI, Dl, MVT::i64,
9084 NewFPSCR =
SDValue(InsertRN, 0);
9091 SDValue Addr = Subtarget.isLittleEndian()
9095 if (Subtarget.isISA3_0()) {
9096 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9098 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9100 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9103 PPC::RLWIMI, Dl, MVT::i32,
9104 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9105 DAG.getTargetConstant(30, Dl, MVT::i32),
9106 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9108 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9111 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9114 if (Subtarget.isISA3_0())
9120 PPC::MTFSF, Dl, MVT::Other,
9148 EVT VT =
Op.getValueType();
9153 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9164 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9168 "Stack slot adjustment is valid only on big endian subtargets!");
9171 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9198 EVT VT =
Op.getValueType();
9202 VT ==
Op.getOperand(1).getValueType() &&
9222 SDValue OutOps[] = { OutLo, OutHi };
9227 EVT VT =
Op.getValueType();
9231 VT ==
Op.getOperand(1).getValueType() &&
9251 SDValue OutOps[] = { OutLo, OutHi };
9257 EVT VT =
Op.getValueType();
9260 VT ==
Op.getOperand(1).getValueType() &&
9280 SDValue OutOps[] = { OutLo, OutHi };
9287 EVT VT =
Op.getValueType();
9294 EVT AmtVT =
Z.getValueType();
9304 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9305 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9317 static const MVT VTys[] = {
9318 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9321 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9324 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9329 EVT CanonicalVT = VTys[SplatSize-1];
9342 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9343 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9352 EVT DestVT = MVT::Other) {
9353 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9362 EVT DestVT = MVT::Other) {
9365 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9377 for (
unsigned i = 0; i != 16; ++i)
9398 EVT VecVT = V->getValueType(0);
9399 bool RightType = VecVT == MVT::v2f64 ||
9400 (HasP8Vector && VecVT == MVT::v4f32) ||
9401 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9405 bool IsSplat =
true;
9406 bool IsLoad =
false;
9412 if (V->isConstant())
9414 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9415 if (V->getOperand(i).isUndef())
9419 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9421 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9423 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9425 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9429 if (V->getOperand(i) != Op0 ||
9430 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9433 return !(IsSplat && IsLoad);
9443 (
Op.getValueType() != MVT::f128))
9448 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9451 if (!Subtarget.isLittleEndian())
9454 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9462 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9463 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9476 APFloat APFloatToConvert = ArgAPFloat;
9477 bool LosesInfo =
true;
9482 ArgAPFloat = APFloatToConvert;
9504 APFloat APFloatToConvert = ArgAPFloat;
9505 bool LosesInfo =
true;
9509 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9518 EVT Ty =
Op->getValueType(0);
9521 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9530 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9534 if (Ty == MVT::v2i64) {
9537 if (MemVT == MVT::i32) {
9539 Opcode = PPCISD::ZEXT_LD_SPLAT;
9541 Opcode = PPCISD::SEXT_LD_SPLAT;
9549 bool IsLittleEndian) {
9555 APInt ConstValue(VTSize, 0);
9559 unsigned BitPos = 0;
9567 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9568 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9572 for (
unsigned J = 0; J < 16; ++J) {
9574 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9576 if (ExtractValue == 0xFF)
9591 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9593 if (Subtarget.hasP10Vector()) {
9594 APInt BitMask(32, 0);
9600 BitMask != 0 && BitMask != 0xffff) {
9602 MachineSDNode *MSDNode =
9614 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9618 APInt APSplatBits, APSplatUndef;
9619 unsigned SplatBitSize;
9621 bool BVNIsConstantSplat =
9623 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9629 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9630 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9633 if ((
Op->getValueType(0) == MVT::v2f64) &&
9636 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9652 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9658 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9666 bool IsSplat64 =
false;
9667 uint64_t SplatBits = 0;
9668 int32_t SextVal = 0;
9669 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9671 if (SplatBitSize <= 32) {
9673 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9674 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9675 bool P9Vector = Subtarget.hasP9Vector();
9676 int32_t
Hi = P9Vector ? 127 : 15;
9677 int32_t
Lo = P9Vector ? -128 : -16;
9678 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9679 SextVal =
static_cast<int32_t
>(SplatBits);
9683 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9684 unsigned NewOpcode = PPCISD::LD_SPLAT;
9690 const SDValue *InputLoad = &
Op.getOperand(0);
9695 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9696 unsigned ElementSize =
9697 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9699 assert(((ElementSize == 2 * MemorySize)
9700 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9701 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9702 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9703 "Unmatched element size and opcode!\n");
9708 unsigned NumUsesOfInputLD = 128 / ElementSize;
9710 if (BVInOp.isUndef())
9725 if (NumUsesOfInputLD == 1 &&
9726 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9727 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9728 Subtarget.hasLFIWAX()))
9736 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9737 Subtarget.isISA3_1() && ElementSize <= 16)
9740 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9742 Subtarget.hasVSX()) {
9749 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9750 LD->getMemoryVT(),
LD->getMemOperand());
9762 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9764 Subtarget.hasP8Vector()))
9770 unsigned SplatSize = SplatBitSize / 8;
9775 if (SplatBits == 0) {
9777 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9789 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9791 Op.getValueType(), DAG, dl);
9793 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9798 if (Subtarget.hasP9Vector() && SplatSize == 1)
9804 if (SextVal >= -16 && SextVal <= 15) {
9807 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9817 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9823 switch (SplatSize) {
9827 IID = Intrinsic::ppc_altivec_vupklsb;
9831 IID = Intrinsic::ppc_altivec_vextsb2w;
9835 IID = Intrinsic::ppc_altivec_vextsb2d;
9842 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9851 if (SextVal >= -32 && SextVal <= 31) {
9856 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9857 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9860 if (VT ==
Op.getValueType())
9869 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9883 static const signed char SplatCsts[] = {
9884 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9885 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9888 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9891 int i = SplatCsts[idx];
9895 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9898 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9900 static const unsigned IIDs[] = {
9901 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9902 Intrinsic::ppc_altivec_vslw
9909 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9911 static const unsigned IIDs[] = {
9912 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9913 Intrinsic::ppc_altivec_vsrw
9920 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9921 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9923 static const unsigned IIDs[] = {
9924 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9925 Intrinsic::ppc_altivec_vrlw
9932 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9934 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9938 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9940 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9944 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9946 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9959 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9960 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9961 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9977 if (LHSID == (1*9+2)*9+3)
return LHS;
9978 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9990 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9991 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9992 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9993 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9996 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9997 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9998 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9999 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10002 for (
unsigned i = 0; i != 16; ++i)
10003 ShufIdxs[i] = (i&3)+0;
10006 for (
unsigned i = 0; i != 16; ++i)
10007 ShufIdxs[i] = (i&3)+4;
10010 for (
unsigned i = 0; i != 16; ++i)
10011 ShufIdxs[i] = (i&3)+8;
10014 for (
unsigned i = 0; i != 16; ++i)
10015 ShufIdxs[i] = (i&3)+12;
10036 const unsigned BytesInVector = 16;
10037 bool IsLE = Subtarget.isLittleEndian();
10041 unsigned ShiftElts = 0, InsertAtByte = 0;
10045 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10046 0, 15, 14, 13, 12, 11, 10, 9};
10047 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10048 1, 2, 3, 4, 5, 6, 7, 8};
10050 ArrayRef<int>
Mask =
N->getMask();
10051 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10063 bool FoundCandidate =
false;
10067 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10070 for (
unsigned i = 0; i < BytesInVector; ++i) {
10071 unsigned CurrentElement =
Mask[i];
10074 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10077 bool OtherElementsInOrder =
true;
10080 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10087 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10088 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10089 OtherElementsInOrder =
false;
10096 if (OtherElementsInOrder) {
10103 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10104 : BigEndianShifts[CurrentElement & 0xF];
10105 Swap = CurrentElement < BytesInVector;
10107 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10108 FoundCandidate =
true;
10113 if (!FoundCandidate)
10123 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10125 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10128 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10137 const unsigned NumHalfWords = 8;
10138 const unsigned BytesInVector = NumHalfWords * 2;
10143 bool IsLE = Subtarget.isLittleEndian();
10147 unsigned ShiftElts = 0, InsertAtByte = 0;
10151 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10152 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10155 uint32_t OriginalOrderLow = 0x1234567;
10156 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10159 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10160 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10177 bool FoundCandidate =
false;
10180 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10181 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10183 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10184 uint32_t TargetOrder = 0x0;
10191 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10192 TargetOrder = OriginalOrderLow;
10196 if (MaskOneElt == VINSERTHSrcElem &&
10197 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10198 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10199 FoundCandidate =
true;
10205 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10207 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10209 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10210 : BigEndianShifts[MaskOneElt & 0x7];
10211 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10212 Swap = MaskOneElt < NumHalfWords;
10213 FoundCandidate =
true;
10219 if (!FoundCandidate)
10231 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10234 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10239 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10254 auto ShuffleMask = SVN->
getMask();
10269 ShuffleMask = CommutedSV->
getMask();
10278 APInt APSplatValue, APSplatUndef;
10279 unsigned SplatBitSize;
10282 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10294 bool IsLE = Subtarget.isLittleEndian();
10295 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10296 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10297 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10299 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10300 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10301 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10309 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10310 SplatVal |= (SplatVal << SplatBitSize);
10313 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10324 assert(
Op.getValueType() == MVT::v1i128 &&
10325 "Only set v1i128 as custom, other type shouldn't reach here!");
10330 if (SHLAmt % 8 == 0) {
10331 std::array<int, 16>
Mask;
10332 std::iota(
Mask.begin(),
Mask.end(), 0);
10333 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10362 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10367 V1 =
Op.getOperand(0);
10368 V2 =
Op.getOperand(1);
10370 EVT VT =
Op.getValueType();
10371 bool isLittleEndian = Subtarget.isLittleEndian();
10373 unsigned ShiftElts, InsertAtByte;
10379 bool IsPermutedLoad =
false;
10381 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10391 if (IsPermutedLoad) {
10392 assert((isLittleEndian || IsFourByte) &&
10393 "Unexpected size for permuted load on big endian target");
10394 SplatIdx += IsFourByte ? 2 : 1;
10395 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10396 "Splat of a value outside of the loaded memory");
10401 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10404 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10406 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10410 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10423 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10426 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10435 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10438 if (Subtarget.hasP9Vector() &&
10448 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10450 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10454 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10459 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10461 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10462 return SplatInsertNode;
10465 if (Subtarget.hasP9Altivec()) {
10467 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10470 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10474 if (Subtarget.hasVSX() &&
10482 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10487 if (Subtarget.hasVSX() &&
10495 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10500 if (Subtarget.hasP9Vector()) {
10520 if (Subtarget.hasVSX()) {
10533 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10541 if (V2.isUndef()) {
10554 (Subtarget.hasP8Altivec() && (
10565 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10575 (Subtarget.hasP8Altivec() && (
10583 ArrayRef<int> PermMask = SVOp->
getMask();
10586 unsigned PFIndexes[4];
10587 bool isFourElementShuffle =
true;
10588 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10590 unsigned EltNo = 8;
10591 for (
unsigned j = 0;
j != 4; ++
j) {
10592 if (PermMask[i * 4 + j] < 0)
10595 unsigned ByteSource = PermMask[i * 4 +
j];
10596 if ((ByteSource & 3) != j) {
10597 isFourElementShuffle =
false;
10602 EltNo = ByteSource / 4;
10603 }
else if (EltNo != ByteSource / 4) {
10604 isFourElementShuffle =
false;
10608 PFIndexes[i] = EltNo;
10616 if (isFourElementShuffle) {
10618 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10619 PFIndexes[2] * 9 + PFIndexes[3];
10622 unsigned Cost = (PFEntry >> 30);
10642 if (V2.isUndef()) V2 = V1;
10644 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10650 unsigned Opcode = PPCISD::VPERM;
10653 bool NeedSwap =
false;
10654 bool isLittleEndian = Subtarget.isLittleEndian();
10655 bool isPPC64 = Subtarget.isPPC64();
10657 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10659 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10660 "XXPERM instead\n");
10661 Opcode = PPCISD::XXPERM;
10669 NeedSwap = !NeedSwap;
10704 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10706 if (V1HasXXSWAPD) {
10709 else if (SrcElt < 16)
10712 if (V2HasXXSWAPD) {
10715 else if (SrcElt > 15)
10724 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10725 if (isLittleEndian)
10727 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10730 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10733 if (V1HasXXSWAPD) {
10737 if (V2HasXXSWAPD) {
10742 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10743 if (ValType != MVT::v2f64)
10749 ShufflesHandledWithVPERM++;
10753 if (Opcode == PPCISD::XXPERM) {
10754 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10756 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10759 dbgs() <<
"With the following permute control vector:\n";
10763 if (Opcode == PPCISD::XXPERM)
10764 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10768 if (isLittleEndian)
10774 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10786 switch (IntrinsicID) {
10790 case Intrinsic::ppc_altivec_vcmpbfp_p:
10794 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10798 case Intrinsic::ppc_altivec_vcmpequb_p:
10802 case Intrinsic::ppc_altivec_vcmpequh_p:
10806 case Intrinsic::ppc_altivec_vcmpequw_p:
10810 case Intrinsic::ppc_altivec_vcmpequd_p:
10811 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10817 case Intrinsic::ppc_altivec_vcmpneb_p:
10818 case Intrinsic::ppc_altivec_vcmpneh_p:
10819 case Intrinsic::ppc_altivec_vcmpnew_p:
10820 case Intrinsic::ppc_altivec_vcmpnezb_p:
10821 case Intrinsic::ppc_altivec_vcmpnezh_p:
10822 case Intrinsic::ppc_altivec_vcmpnezw_p:
10823 if (Subtarget.hasP9Altivec()) {
10824 switch (IntrinsicID) {
10827 case Intrinsic::ppc_altivec_vcmpneb_p:
10830 case Intrinsic::ppc_altivec_vcmpneh_p:
10833 case Intrinsic::ppc_altivec_vcmpnew_p:
10836 case Intrinsic::ppc_altivec_vcmpnezb_p:
10839 case Intrinsic::ppc_altivec_vcmpnezh_p:
10842 case Intrinsic::ppc_altivec_vcmpnezw_p:
10850 case Intrinsic::ppc_altivec_vcmpgefp_p:
10854 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10858 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10862 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10866 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10870 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10871 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10877 case Intrinsic::ppc_altivec_vcmpgtub_p:
10881 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10885 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10889 case Intrinsic::ppc_altivec_vcmpgtud_p:
10890 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10897 case Intrinsic::ppc_altivec_vcmpequq:
10898 case Intrinsic::ppc_altivec_vcmpgtsq:
10899 case Intrinsic::ppc_altivec_vcmpgtuq:
10900 if (!Subtarget.isISA3_1())
10902 switch (IntrinsicID) {
10905 case Intrinsic::ppc_altivec_vcmpequq:
10908 case Intrinsic::ppc_altivec_vcmpgtsq:
10911 case Intrinsic::ppc_altivec_vcmpgtuq:
10918 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10919 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10920 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10921 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10922 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10923 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10924 if (Subtarget.hasVSX()) {
10925 switch (IntrinsicID) {
10926 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10929 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10932 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10935 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10938 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10941 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10951 case Intrinsic::ppc_altivec_vcmpbfp:
10954 case Intrinsic::ppc_altivec_vcmpeqfp:
10957 case Intrinsic::ppc_altivec_vcmpequb:
10960 case Intrinsic::ppc_altivec_vcmpequh:
10963 case Intrinsic::ppc_altivec_vcmpequw:
10966 case Intrinsic::ppc_altivec_vcmpequd:
10967 if (Subtarget.hasP8Altivec())
10972 case Intrinsic::ppc_altivec_vcmpneb:
10973 case Intrinsic::ppc_altivec_vcmpneh:
10974 case Intrinsic::ppc_altivec_vcmpnew:
10975 case Intrinsic::ppc_altivec_vcmpnezb:
10976 case Intrinsic::ppc_altivec_vcmpnezh:
10977 case Intrinsic::ppc_altivec_vcmpnezw:
10978 if (Subtarget.hasP9Altivec())
10979 switch (IntrinsicID) {
10982 case Intrinsic::ppc_altivec_vcmpneb:
10985 case Intrinsic::ppc_altivec_vcmpneh:
10988 case Intrinsic::ppc_altivec_vcmpnew:
10991 case Intrinsic::ppc_altivec_vcmpnezb:
10994 case Intrinsic::ppc_altivec_vcmpnezh:
10997 case Intrinsic::ppc_altivec_vcmpnezw:
11004 case Intrinsic::ppc_altivec_vcmpgefp:
11007 case Intrinsic::ppc_altivec_vcmpgtfp:
11010 case Intrinsic::ppc_altivec_vcmpgtsb:
11013 case Intrinsic::ppc_altivec_vcmpgtsh:
11016 case Intrinsic::ppc_altivec_vcmpgtsw:
11019 case Intrinsic::ppc_altivec_vcmpgtsd:
11020 if (Subtarget.hasP8Altivec())
11025 case Intrinsic::ppc_altivec_vcmpgtub:
11028 case Intrinsic::ppc_altivec_vcmpgtuh:
11031 case Intrinsic::ppc_altivec_vcmpgtuw:
11034 case Intrinsic::ppc_altivec_vcmpgtud:
11035 if (Subtarget.hasP8Altivec())
11040 case Intrinsic::ppc_altivec_vcmpequq_p:
11041 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11042 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11043 if (!Subtarget.isISA3_1())
11045 switch (IntrinsicID) {
11048 case Intrinsic::ppc_altivec_vcmpequq_p:
11051 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11054 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11068 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11074 auto MapNodeWithSplatVector =
11075 [&](
unsigned Opcode,
11076 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11081 Ops.append(ExtraOps.begin(), ExtraOps.end());
11082 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11085 switch (IntrinsicID) {
11086 case Intrinsic::thread_pointer:
11088 if (Subtarget.isPPC64())
11092 case Intrinsic::ppc_rldimi: {
11093 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11095 APInt
Mask =
Op.getConstantOperandAPInt(4);
11097 return Op.getOperand(2);
11098 if (
Mask.isAllOnes())
11100 uint64_t SH =
Op.getConstantOperandVal(3);
11101 unsigned MB = 0, ME = 0;
11105 if (ME < 63 - SH) {
11108 }
else if (ME > 63 - SH) {
11114 {Op.getOperand(2), Src,
11115 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11116 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11120 case Intrinsic::ppc_rlwimi: {
11121 APInt
Mask =
Op.getConstantOperandAPInt(4);
11123 return Op.getOperand(2);
11124 if (
Mask.isAllOnes())
11127 unsigned MB = 0, ME = 0;
11131 PPC::RLWIMI, dl, MVT::i32,
11132 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11133 DAG.getTargetConstant(MB, dl, MVT::i32),
11134 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11138 case Intrinsic::ppc_bcdshift:
11139 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11140 case Intrinsic::ppc_bcdshiftround:
11141 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11142 case Intrinsic::ppc_bcdtruncate:
11143 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11144 case Intrinsic::ppc_bcdunsignedtruncate:
11145 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11146 case Intrinsic::ppc_bcdunsignedshift:
11147 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11149 case Intrinsic::ppc_rlwnm: {
11150 if (
Op.getConstantOperandVal(3) == 0)
11152 unsigned MB = 0, ME = 0;
11157 {Op.getOperand(1), Op.getOperand(2),
11158 DAG.getTargetConstant(MB, dl, MVT::i32),
11159 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11163 case Intrinsic::ppc_mma_disassemble_acc: {
11164 if (Subtarget.isISAFuture()) {
11165 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11176 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11177 Subtarget.isLittleEndian() ? Value2 :
Value,
11178 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11182 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11183 Subtarget.isLittleEndian() ? Value2 :
Value,
11184 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11188 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11189 Subtarget.isLittleEndian() ?
Value : Value2,
11190 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11194 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11195 Subtarget.isLittleEndian() ?
Value : Value2,
11196 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11203 case Intrinsic::ppc_vsx_disassemble_pair: {
11206 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11208 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11211 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11213 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11214 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11222 case Intrinsic::ppc_build_dmr: {
11225 for (
int i = 1; i < 9; i += 2) {
11233 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11240 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11241 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11243 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11244 "Specify P of 0 or 1 for lower or upper 512 bytes");
11245 unsigned HiLo = Idx->getSExtValue();
11249 Opcode = PPC::DMXXEXTFDMR512;
11250 Subx = PPC::sub_wacc_lo;
11252 Opcode = PPC::DMXXEXTFDMR512_HI;
11253 Subx = PPC::sub_wacc_hi;
11256 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11260 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11264 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11265 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11267 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11268 "Specify a dmr row pair 0-3");
11269 unsigned IdxVal = Idx->getSExtValue();
11273 Subx = PPC::sub_dmrrowp0;
11276 Subx = PPC::sub_dmrrowp1;
11279 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11282 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11286 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11292 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11296 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11297 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11299 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11300 "Specify P of 0 or 1 for lower or upper 512 bytes");
11301 unsigned HiLo = Idx->getSExtValue();
11305 Opcode = PPCISD::INST512;
11306 Subx = PPC::sub_wacc_lo;
11308 Opcode = PPCISD::INST512HI;
11309 Subx = PPC::sub_wacc_hi;
11315 Op.getOperand(1), Wacc, SubReg),
11319 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11320 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11322 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11323 "Specify a dmr row pair 0-3");
11324 unsigned IdxVal = Idx->getSExtValue();
11328 Subx = PPC::sub_dmrrowp0;
11331 Subx = PPC::sub_dmrrowp1;
11334 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11337 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11343 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11345 Op.getOperand(1), DMRRowp, SubReg),
11349 case Intrinsic::ppc_mma_xxmfacc:
11350 case Intrinsic::ppc_mma_xxmtacc: {
11352 if (!Subtarget.isISAFuture())
11363 case Intrinsic::ppc_unpack_longdouble: {
11365 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11366 "Argument of long double unpack must be 0 or 1!");
11369 Idx->getValueType(0)));
11372 case Intrinsic::ppc_compare_exp_lt:
11373 case Intrinsic::ppc_compare_exp_gt:
11374 case Intrinsic::ppc_compare_exp_eq:
11375 case Intrinsic::ppc_compare_exp_uo: {
11377 switch (IntrinsicID) {
11378 case Intrinsic::ppc_compare_exp_lt:
11381 case Intrinsic::ppc_compare_exp_gt:
11384 case Intrinsic::ppc_compare_exp_eq:
11387 case Intrinsic::ppc_compare_exp_uo:
11393 PPC::SELECT_CC_I4, dl, MVT::i32,
11394 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11395 Op.getOperand(1), Op.getOperand(2)),
11397 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11398 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11401 case Intrinsic::ppc_test_data_class: {
11402 EVT OpVT =
Op.getOperand(1).getValueType();
11403 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11404 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11417 {Op.getOperand(2), Op.getOperand(1)}),
11419 if (Subtarget.isISA3_1()) {
11426 TestDataClass, SubRegIdx),
11429 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11435 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11436 DAG.getConstant(0, dl, MVT::i32),
11437 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11440 case Intrinsic::ppc_fnmsub: {
11441 EVT VT =
Op.getOperand(1).getValueType();
11442 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11447 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11448 Op.getOperand(2),
Op.getOperand(3));
11450 case Intrinsic::ppc_convert_f128_to_ppcf128:
11451 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11452 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11453 ? RTLIB::CONVERT_PPCF128_F128
11454 : RTLIB::CONVERT_F128_PPCF128;
11456 std::pair<SDValue, SDValue>
Result =
11457 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11461 case Intrinsic::ppc_maxfe:
11462 case Intrinsic::ppc_maxfl:
11463 case Intrinsic::ppc_maxfs:
11464 case Intrinsic::ppc_minfe:
11465 case Intrinsic::ppc_minfl:
11466 case Intrinsic::ppc_minfs: {
11467 EVT VT =
Op.getValueType();
11470 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11471 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11474 if (IntrinsicID == Intrinsic::ppc_minfe ||
11475 IntrinsicID == Intrinsic::ppc_minfl ||
11476 IntrinsicID == Intrinsic::ppc_minfs)
11497 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11498 Op.getOperand(1),
Op.getOperand(2),
11509 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11517 switch (
Op.getConstantOperandVal(1)) {
11522 Bitx = PPC::sub_eq;
11523 SetOp = PPCISD::SETBC;
11528 Bitx = PPC::sub_eq;
11529 SetOp = PPCISD::SETBCR;
11534 Bitx = PPC::sub_lt;
11535 SetOp = PPCISD::SETBC;
11540 Bitx = PPC::sub_lt;
11541 SetOp = PPCISD::SETBCR;
11546 if (Subtarget.isISA3_1()) {
11551 CR6Reg, SubRegIdx, GlueOp),
11553 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11581 switch (
Op.getConstantOperandVal(ArgStart)) {
11582 case Intrinsic::ppc_cfence: {
11583 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11584 SDValue Val =
Op.getOperand(ArgStart + 1);
11586 if (Ty == MVT::i128) {
11591 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11594 Opcode,
DL, MVT::Other,
11599 case Intrinsic::ppc_disassemble_dmr: {
11601 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11602 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11603 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11605 case Intrinsic::ppc_amo_stwat:
11606 case Intrinsic::ppc_amo_stdat: {
11609 SDValue Ptr =
Op.getOperand(ArgStart + 1);
11610 SDValue Val =
Op.getOperand(ArgStart + 2);
11613 return DAG.
getNode(PPCISD::STAT, dl, MVT::Other, Chain, Val, Ptr, FC);
11624 if (!Subtarget.isPPC64())
11632 int VectorIndex = 0;
11633 if (Subtarget.isLittleEndian())
11645 "Expecting an atomic compare-and-swap here.");
11648 EVT MemVT = AtomicNode->getMemoryVT();
11666 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11667 Ops.push_back(AtomicNode->getOperand(i));
11669 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11670 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11672 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11679 EVT MemVT =
N->getMemoryVT();
11681 "Expect quadword atomic operations");
11683 unsigned Opc =
N->getOpcode();
11688 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11691 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11692 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11693 Ops.push_back(
N->getOperand(
I));
11695 Ops, MemVT,
N->getMemOperand());
11702 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11709 SDVTList Tys = DAG.
getVTList(MVT::Other);
11712 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11718 Ops.push_back(ValLo);
11719 Ops.push_back(ValHi);
11720 Ops.push_back(
N->getOperand(2));
11722 N->getMemOperand());
11734 enum DataClassMask {
11736 DC_NEG_INF = 1 << 4,
11737 DC_POS_INF = 1 << 5,
11738 DC_NEG_ZERO = 1 << 2,
11739 DC_POS_ZERO = 1 << 3,
11740 DC_NEG_SUBNORM = 1,
11741 DC_POS_SUBNORM = 1 << 1,
11744 EVT VT =
Op.getValueType();
11746 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11747 : VT == MVT::f64 ? PPC::XSTSTDCDP
11758 return DAG.
getNOT(Dl, Rev, MVT::i1);
11765 TestOp, Dl, MVT::i32,
11767 DC_NEG_ZERO | DC_POS_ZERO |
11768 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11774 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11780 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11785 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11798 bool IsQuiet = Mask &
fcQNan;
11804 if (VT == MVT::f128) {
11808 QuietMask = 0x8000;
11809 }
else if (VT == MVT::f64) {
11810 if (Subtarget.isPPC64()) {
11821 QuietMask = 0x80000;
11822 }
else if (VT == MVT::f32) {
11824 QuietMask = 0x400000;
11840 unsigned NativeMask = 0;
11842 NativeMask |= DC_NAN;
11844 NativeMask |= DC_NEG_INF;
11846 NativeMask |= DC_POS_INF;
11848 NativeMask |= DC_NEG_ZERO;
11850 NativeMask |= DC_POS_ZERO;
11852 NativeMask |= DC_NEG_SUBNORM;
11854 NativeMask |= DC_POS_SUBNORM;
11857 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11859 TestOp, Dl, MVT::i32,
11868 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11870 uint64_t RHSC =
Op.getConstantOperandVal(1);
11873 if (
LHS.getValueType() == MVT::ppcf128) {
11897 bool Future = Subtarget.isISAFuture();
11900 "Mask predication not supported");
11903 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11904 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11908 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11911 VPLD->getMemoryVT(), VPLD->getMemOperand());
11918 "Mask predication not supported");
11923 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11924 bool Future = Subtarget.isISAFuture();
11925 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11928 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11931 SDVTList Tys = DAG.
getVTList(MVT::Other);
11934 VPST->getMemoryVT(), VPST->getMemOperand());
11945 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11947 int64_t
IntVal =
Op.getConstantOperandVal(0);
11948 if (IntVal >= -16 && IntVal <= 15)
11954 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11959 MachineMemOperand *MMO =
11961 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11964 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
11968 return Bits.getValue(0);
11984 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11989 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11996 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11997 MachinePointerInfo());
12004 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
12010 "Should only be called for ISD::INSERT_VECTOR_ELT");
12014 EVT VT =
Op.getValueType();
12019 if (VT == MVT::v2f64 &&
C)
12022 if (Subtarget.hasP9Vector()) {
12031 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12037 BitcastLoad,
Op.getOperand(2));
12038 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12042 if (Subtarget.isISA3_1()) {
12043 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12047 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12048 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12058 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12061 unsigned InsertAtElement =
C->getZExtValue();
12062 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12063 if (Subtarget.isLittleEndian()) {
12064 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12066 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
12078 EVT VT =
Op.getValueType();
12079 bool IsV1024i1 = VT == MVT::v1024i1;
12080 bool IsV2048i1 = VT == MVT::v2048i1;
12084 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12086 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12087 "Dense Math support required.");
12088 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12097 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12098 MachineMemOperand *NewMMO =
12106 DAG.
getVTList(MVT::v256i1, MVT::Other),
12107 LoadOps, MVT::v256i1, NewMMO);
12112 if (Subtarget.isLittleEndian()) {
12113 std::reverse(Loads.
begin(), Loads.
end());
12114 std::reverse(LoadChains.
begin(), LoadChains.
end());
12126 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12132 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12135 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12144 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12147 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12152 {RC, Lo, LoSub, Hi, HiSub}),
12162 EVT VT =
Op.getValueType();
12164 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12165 return LowerDMFVectorLoad(
Op, DAG);
12167 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12171 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12172 "Type unsupported without MMA");
12173 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12174 "Type unsupported without paired vector support");
12178 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12187 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12189 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12198 if (Subtarget.isLittleEndian()) {
12199 std::reverse(Loads.
begin(), Loads.
end());
12200 std::reverse(LoadChains.
begin(), LoadChains.
end());
12204 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12220 bool IsV1024i1 = VT == MVT::v1024i1;
12221 bool IsV2048i1 = VT == MVT::v2048i1;
12225 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12227 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12228 "Dense Math support required.");
12229 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12231 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12234 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12239 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12243 MachineSDNode *ExtNode =
12247 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12253 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12259 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12265 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12270 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12275 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12280 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12284 MachineSDNode *ExtNode =
12285 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12289 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12292 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12296 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12301 if (Subtarget.isLittleEndian())
12302 std::reverse(Values.
begin(), Values.
end());
12304 SDVTList Tys = DAG.
getVTList(MVT::Other);
12306 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12310 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12311 MachineMemOperand *NewMMO =
12318 Ops[2] = Values[Idx];
12320 MVT::v256i1, NewMMO);
12336 EVT StoreVT =
Value.getValueType();
12338 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12339 return LowerDMFVectorStore(
Op, DAG);
12341 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12345 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12346 "Type unsupported without MMA");
12347 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12348 "Type unsupported without paired vector support");
12352 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12360 unsigned NumVecs = 2;
12361 if (StoreVT == MVT::v512i1) {
12362 if (Subtarget.isISAFuture()) {
12363 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12365 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12368 Value2 =
SDValue(ExtNode, 1);
12373 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12374 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12376 if (Subtarget.isISAFuture()) {
12377 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12378 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12379 Idx > 1 ? Value2 :
Value,
12382 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12386 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12400 if (
Op.getValueType() == MVT::v4i32) {
12417 LHS,
RHS, DAG, dl, MVT::v4i32);
12420 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12425 }
else if (
Op.getValueType() == MVT::v16i8) {
12427 bool isLittleEndian = Subtarget.isLittleEndian();
12431 LHS,
RHS, DAG, dl, MVT::v8i16);
12436 LHS,
RHS, DAG, dl, MVT::v8i16);
12444 for (
unsigned i = 0; i != 8; ++i) {
12445 if (isLittleEndian) {
12447 Ops[i*2+1] = 2*i+16;
12450 Ops[i*2+1] = 2*i+1+16;
12453 if (isLittleEndian)
12463 bool IsStrict =
Op->isStrictFPOpcode();
12464 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12465 !Subtarget.hasP9Vector())
12475 "Should only be called for ISD::FP_EXTEND");
12479 if (
Op.getValueType() != MVT::v2f64 ||
12480 Op.getOperand(0).getValueType() != MVT::v2f32)
12492 "Node should have 2 operands with second one being a constant!");
12504 int DWord = Idx >> 1;
12507 if (Subtarget.isLittleEndian())
12510 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12524 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12526 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12527 LD->getMemoryVT(),
LD->getMemOperand());
12532 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12537 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12539 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12540 LD->getMemoryVT(),
LD->getMemOperand());
12541 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12552 if (STI.useCRBits())
12569 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12570 if (STI.useCRBits())
12578 SDNode *
N =
Op.getNode();
12579 EVT VT =
N->getValueType(0);
12580 EVT CarryType =
N->getValueType(1);
12581 unsigned Opc =
N->getOpcode();
12583 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12585 N->getOperand(0),
N->getOperand(1));
12597 SDNode *
N =
Op.getNode();
12598 unsigned Opc =
N->getOpcode();
12599 EVT VT =
N->getValueType(0);
12600 EVT CarryType =
N->getValueType(1);
12601 SDValue CarryOp =
N->getOperand(2);
12603 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12609 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12623 EVT VT =
Op.getNode()->getValueType(0);
12649 EVT VT =
Op.getNode()->getValueType(0);
12678 EVT OpVT =
A.getValueType();
12679 EVT ResVT =
Op.getValueType();
12684 if (Subtarget.isPPC64() && OpVT == MVT::i32) {
12694 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12712 switch (
Op.getOpcode()) {
12732 return LowerSSUBO(
Op, DAG);
12734 return LowerSADDO(
Op, DAG);
12746 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12767 return LowerSET_ROUNDING(
Op, DAG);
12774 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12775 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12787 return LowerFP_ROUND(
Op, DAG);
12801 return LowerINTRINSIC_VOID(
Op, DAG);
12803 return LowerBSWAP(
Op, DAG);
12805 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12807 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12809 return LowerIS_FPCLASS(
Op, DAG);
12812 return LowerADDSUBO(
Op, DAG);
12815 return LowerADDSUBO_CARRY(
Op, DAG);
12817 return LowerUCMP(
Op, DAG);
12823 if (
Op->getFlags().hasNoFPExcept())
12827 return LowerVP_LOAD(
Op, DAG);
12828 case ISD::VP_STORE:
12829 return LowerVP_STORE(
Op, DAG);
12837 switch (
N->getOpcode()) {
12839 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12856 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12859 assert(
N->getValueType(0) == MVT::i1 &&
12860 "Unexpected result type for CTR decrement intrinsic");
12862 N->getValueType(0));
12872 switch (
N->getConstantOperandVal(0)) {
12873 case Intrinsic::ppc_pack_longdouble:
12875 N->getOperand(2),
N->getOperand(1)));
12877 case Intrinsic::ppc_maxfe:
12878 case Intrinsic::ppc_minfe:
12879 case Intrinsic::ppc_fnmsub:
12880 case Intrinsic::ppc_convert_f128_to_ppcf128:
12887 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12890 EVT VT =
N->getValueType(0);
12892 if (VT == MVT::i64) {
12905 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12909 Results.push_back(LoweredValue);
12910 if (
N->isStrictFPOpcode())
12915 if (!
N->getValueType(0).isVector())
12948 return Builder.CreateIntrinsic(Id, {});
12954 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12956 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12957 "Only 8/16/32/64-bit atomic loads supported");
12963 IntID = Intrinsic::ppc_lbarx;
12964 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12967 IntID = Intrinsic::ppc_lharx;
12968 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12971 IntID = Intrinsic::ppc_lwarx;
12974 IntID = Intrinsic::ppc_ldarx;
12978 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12980 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12991 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12992 "Only 8/16/32/64-bit atomic loads supported");
12998 IntID = Intrinsic::ppc_stbcx;
12999 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13002 IntID = Intrinsic::ppc_sthcx;
13003 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13006 IntID = Intrinsic::ppc_stwcx;
13009 IntID = Intrinsic::ppc_stdcx;
13013 if (SZ == 8 || SZ == 16)
13014 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13016 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13018 return Builder.CreateXor(
Call, Builder.getInt32(1));
13041 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
13051 unsigned BinOpcode,
13052 unsigned CmpOpcode,
13053 unsigned CmpPred)
const {
13058 unsigned AtomicSize =
MI.getOperand(3).getImm();
13060 auto LoadMnemonic = PPC::LDARX;
13061 auto StoreMnemonic = PPC::STDCX;
13062 switch (AtomicSize) {
13066 LoadMnemonic = PPC::LBARX;
13067 StoreMnemonic = PPC::STBCX;
13068 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13071 LoadMnemonic = PPC::LHARX;
13072 StoreMnemonic = PPC::STHCX;
13073 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13076 LoadMnemonic = PPC::LWARX;
13077 StoreMnemonic = PPC::STWCX;
13080 LoadMnemonic = PPC::LDARX;
13081 StoreMnemonic = PPC::STDCX;
13089 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13100 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13102 F->insert(It, loopMBB);
13104 F->insert(It, loop2MBB);
13105 F->insert(It, exitMBB);
13111 Register TmpReg = (!BinOpcode) ? incr :
13112 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13113 : &PPC::GPRCRegClass);
13138 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13143 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13145 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13146 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13147 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13177 switch(
MI.getOpcode()) {
13181 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13182 &
MI.getMF()->getRegInfo());
13206 case PPC::EXTSB8_32_64:
13207 case PPC::EXTSB8_rec:
13208 case PPC::EXTSB_rec:
13211 case PPC::EXTSH8_32_64:
13212 case PPC::EXTSH8_rec:
13213 case PPC::EXTSH_rec:
13215 case PPC::EXTSWSLI:
13216 case PPC::EXTSWSLI_32_64:
13217 case PPC::EXTSWSLI_32_64_rec:
13218 case PPC::EXTSWSLI_rec:
13219 case PPC::EXTSW_32:
13220 case PPC::EXTSW_32_64:
13221 case PPC::EXTSW_32_64_rec:
13222 case PPC::EXTSW_rec:
13225 case PPC::SRAWI_rec:
13226 case PPC::SRAW_rec:
13236 unsigned OpIdx,
bool IsByte,
13241 bool IsSignExtended =
13244 if (!IsSignExtended) {
13245 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13247 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13249 MI.getOperand(
OpIdx).setReg(ValueReg);
13255 unsigned CmpOpcode,
unsigned CmpPred)
const {
13259 assert(!Subtarget.hasPartwordAtomics() &&
13260 "Assumes that part-word atomics are not available");
13268 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13269 if (CmpOpcode == PPC::CMPW)
13277 bool is64bit = Subtarget.isPPC64();
13278 bool isLittleEndian = Subtarget.isLittleEndian();
13279 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13290 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13292 F->insert(It, loopMBB);
13294 F->insert(It, loop2MBB);
13295 F->insert(It, exitMBB);
13301 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13304 Register PtrReg = RegInfo.createVirtualRegister(RC);
13305 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13307 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13308 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13309 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13310 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13311 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13312 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13313 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13314 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13315 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13316 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13319 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13346 if (ptrA != ZeroReg) {
13347 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13348 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13356 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13357 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13360 .
addImm(is8bit ? 28 : 27);
13361 if (!isLittleEndian)
13362 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13364 .
addImm(is8bit ? 24 : 16);
13366 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13371 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13381 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13385 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13390 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13394 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13397 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13404 Register SReg = RegInfo.createVirtualRegister(GPRC);
13405 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13409 unsigned ValueReg = SReg;
13410 unsigned CmpReg = Incr2Reg;
13411 if (CmpOpcode == PPC::CMPW) {
13412 ValueReg = RegInfo.createVirtualRegister(GPRC);
13413 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13416 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13417 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13419 ValueReg = ValueSReg;
13451 .
addImm(is8bit ? 24 : 16)
13472 Register DstReg =
MI.getOperand(0).getReg();
13474 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13479 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13480 "Invalid Pointer Size!");
13529 Register BufReg =
MI.getOperand(1).getReg();
13531 if (Subtarget.is64BitELFABI()) {
13544 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13546 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13549 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13572 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13575 if (Subtarget.isPPC64()) {
13593 TII->get(PPC::PHI), DstReg)
13597 MI.eraseFromParent();
13611 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13612 "Invalid Pointer Size!");
13615 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13618 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13619 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13633 Register BufReg =
MI.getOperand(0).getReg();
13638 if (PVT == MVT::i64) {
13650 if (PVT == MVT::i64) {
13662 if (PVT == MVT::i64) {
13674 if (PVT == MVT::i64) {
13686 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13696 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13699 MI.eraseFromParent();
13715 "Unexpected stack alignment");
13719 unsigned StackProbeSize =
13722 StackProbeSize &= ~(StackAlign - 1);
13723 return StackProbeSize ? StackProbeSize : StackAlign;
13735 const bool isPPC64 = Subtarget.isPPC64();
13767 MF->
insert(MBBIter, TestMBB);
13768 MF->
insert(MBBIter, BlockMBB);
13769 MF->
insert(MBBIter, TailMBB);
13774 Register DstReg =
MI.getOperand(0).getReg();
13775 Register NegSizeReg =
MI.getOperand(1).getReg();
13787 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13793 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13794 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13796 .
addDef(ActualNegSizeReg)
13798 .
add(
MI.getOperand(2))
13799 .
add(
MI.getOperand(3));
13805 .
addReg(ActualNegSizeReg);
13808 int64_t NegProbeSize = -(int64_t)ProbeSize;
13814 .
addImm(NegProbeSize >> 16);
13818 .
addImm(NegProbeSize & 0xFFFF);
13827 .
addReg(ActualNegSizeReg)
13836 .
addReg(ActualNegSizeReg);
13846 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13873 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13874 MaxCallFrameSizeReg)
13875 .
add(
MI.getOperand(2))
13876 .
add(
MI.getOperand(3));
13877 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13879 .
addReg(MaxCallFrameSizeReg);
13885 MBB->addSuccessor(TestMBB);
13888 MI.eraseFromParent();
13890 ++NumDynamicAllocaProbed;
13898static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
13901 case PPC::SELECT_CC_I4:
13902 case PPC::SELECT_CC_I8:
13903 case PPC::SELECT_CC_F4:
13904 case PPC::SELECT_CC_F8:
13905 case PPC::SELECT_CC_F16:
13906 case PPC::SELECT_CC_VRRC:
13907 case PPC::SELECT_CC_VSFRC:
13908 case PPC::SELECT_CC_VSSRC:
13909 case PPC::SELECT_CC_VSRC:
13910 case PPC::SELECT_CC_SPE4:
13911 case PPC::SELECT_CC_SPE:
13914 case PPC::SELECT_I4:
13915 case PPC::SELECT_I8:
13916 case PPC::SELECT_F4:
13917 case PPC::SELECT_F8:
13918 case PPC::SELECT_F16:
13919 case PPC::SELECT_SPE:
13920 case PPC::SELECT_SPE4:
13921 case PPC::SELECT_VRRC:
13922 case PPC::SELECT_VSFRC:
13923 case PPC::SELECT_VSSRC:
13924 case PPC::SELECT_VSRC:
13925 return !CheckOnlyCC;
13941 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
13944 if (Subtarget.hasISEL() &&
13945 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13946 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13947 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13949 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13950 MI.getOpcode() == PPC::SELECT_CC_I8)
13951 Cond.push_back(
MI.getOperand(4));
13954 Cond.push_back(
MI.getOperand(1));
13957 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13958 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13959 MI.eraseFromParent();
13972 F->insert(It, copy0MBB);
13973 F->insert(It, sinkMBB);
13981 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13997 .
addImm(
MI.getOperand(4).getImm())
13998 .
addReg(
MI.getOperand(1).getReg())
14002 .
addReg(
MI.getOperand(1).getReg())
14012 .
addReg(
MI.getOperand(3).getReg())
14014 .
addReg(
MI.getOperand(2).getReg())
14016 MI.eraseFromParent();
14031 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14032 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14033 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14034 F->insert(It, loop1MBB);
14035 F->insert(It, loop2MBB);
14036 F->insert(It, exitMBB);
14071 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14073 unsigned LoadMnemonic = PPC::LDARX;
14074 unsigned StoreMnemonic = PPC::STDCX;
14075 switch (
MI.getOpcode()) {
14078 case PPC::ATOMIC_CMP_SWAP_I8:
14079 LoadMnemonic = PPC::LBARX;
14080 StoreMnemonic = PPC::STBCX;
14081 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14083 case PPC::ATOMIC_CMP_SWAP_I16:
14084 LoadMnemonic = PPC::LHARX;
14085 StoreMnemonic = PPC::STHCX;
14086 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14088 case PPC::ATOMIC_CMP_SWAP_I32:
14089 LoadMnemonic = PPC::LWARX;
14090 StoreMnemonic = PPC::STWCX;
14092 case PPC::ATOMIC_CMP_SWAP_I64:
14093 LoadMnemonic = PPC::LDARX;
14094 StoreMnemonic = PPC::STDCX;
14102 Register oldval =
MI.getOperand(3).getReg();
14103 Register newval =
MI.getOperand(4).getReg();
14117 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14185 bool is64bit = Subtarget.isPPC64();
14187 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14192 Register oldval =
MI.getOperand(3).getReg();
14193 Register newval =
MI.getOperand(4).getReg();
14201 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14206 return RegInfo.createVirtualRegister(RC);
14210 Register Shift1Reg = createVReg(GPRC);
14211 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14212 Register NewVal2Reg = createVReg(GPRC);
14213 Register NewVal3Reg = createVReg(GPRC);
14214 Register OldVal2Reg = createVReg(GPRC);
14215 Register OldVal3Reg = createVReg(GPRC);
14216 Register MaskReg = createVReg(GPRC);
14217 Register Mask2Reg = createVReg(GPRC);
14218 Register Mask3Reg = createVReg(GPRC);
14219 Register Tmp2Reg = createVReg(GPRC);
14220 Register Tmp4Reg = createVReg(GPRC);
14221 Register TmpDestReg = createVReg(GPRC);
14222 Register TmpReg = createVReg(GPRC);
14223 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14224 Register CrReg = createVReg(&PPC::CRRCRegClass);
14228 if (ptrA != ZeroReg) {
14229 Ptr1Reg = createVReg(RC);
14230 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14237 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14238 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14241 .
addImm(is8bit ? 28 : 27);
14242 if (!isLittleEndian)
14243 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14245 .
addImm(is8bit ? 24 : 16);
14247 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14252 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14259 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14262 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14269 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14273 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14276 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14279 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14289 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14310 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14355 switch (
MI.getOpcode()) {
14356 case TargetOpcode::STACKMAP:
14358 case TargetOpcode::PATCHPOINT:
14364 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14368 case PPC::EH_SjLj_SetJmp32:
14369 case PPC::EH_SjLj_SetJmp64:
14372 case PPC::EH_SjLj_LongJmp32:
14373 case PPC::EH_SjLj_LongJmp64:
14376 case PPC::ReadTB: {
14392 F->insert(It, readMBB);
14393 F->insert(It, sinkMBB);
14404 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14412 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14414 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14426 case PPC::ATOMIC_LOAD_ADD_NOWP:
14429 case PPC::ATOMIC_LOAD_ADD:
14432 case PPC::ATOMIC_LOAD_ADD_I64:
14435 case PPC::ATOMIC_LOAD_AND_NOWP:
14438 case PPC::ATOMIC_LOAD_AND:
14441 case PPC::ATOMIC_LOAD_AND_I64:
14444 case PPC::ATOMIC_LOAD_OR_NOWP:
14447 case PPC::ATOMIC_LOAD_OR:
14450 case PPC::ATOMIC_LOAD_OR_I64:
14453 case PPC::ATOMIC_LOAD_XOR_NOWP:
14456 case PPC::ATOMIC_LOAD_XOR:
14459 case PPC::ATOMIC_LOAD_XOR_I64:
14462 case PPC::ATOMIC_LOAD_NAND_NOWP:
14465 case PPC::ATOMIC_LOAD_NAND:
14468 case PPC::ATOMIC_LOAD_NAND_I64:
14471 case PPC::ATOMIC_LOAD_SUB_NOWP:
14474 case PPC::ATOMIC_LOAD_SUB:
14477 case PPC::ATOMIC_LOAD_SUB_I64:
14480 case PPC::ATOMIC_LOAD_MIN_NOWP:
14483 case PPC::ATOMIC_LOAD_MIN:
14486 case PPC::ATOMIC_LOAD_MIN_I64:
14489 case PPC::ATOMIC_LOAD_MAX_NOWP:
14492 case PPC::ATOMIC_LOAD_MAX:
14495 case PPC::ATOMIC_LOAD_MAX_I64:
14498 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14501 case PPC::ATOMIC_LOAD_UMIN:
14504 case PPC::ATOMIC_LOAD_UMIN_I64:
14507 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14510 case PPC::ATOMIC_LOAD_UMAX:
14513 case PPC::ATOMIC_LOAD_UMAX_I64:
14516 case PPC::ATOMIC_SWAP_NOWP:
14519 case PPC::ATOMIC_SWAP:
14520 case PPC::ATOMIC_SWAP_I64:
14523 case PPC::ATOMIC_CMP_SWAP_I32:
14524 case PPC::ATOMIC_CMP_SWAP_I64:
14525 case PPC::ATOMIC_CMP_SWAP_I8:
14526 case PPC::ATOMIC_CMP_SWAP_I16: {
14528 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14529 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14530 (Subtarget.hasPartwordAtomics() &&
14531 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14532 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14540 case PPC::FADDrtz: {
14550 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14565 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14575 case PPC::ANDI_rec_1_EQ_BIT:
14576 case PPC::ANDI_rec_1_GT_BIT:
14577 case PPC::ANDI_rec_1_EQ_BIT8:
14578 case PPC::ANDI_rec_1_GT_BIT8: {
14579 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14580 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14583 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14584 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14587 Register Dest = RegInfo.createVirtualRegister(
14588 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14592 .
addReg(
MI.getOperand(1).getReg())
14595 MI.getOperand(0).getReg())
14596 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14599 case PPC::TCHECK_RET: {
14602 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14605 MI.getOperand(0).getReg())
14609 case PPC::TBEGIN_RET: {
14611 unsigned Imm =
MI.getOperand(1).getImm();
14614 MI.getOperand(0).getReg())
14618 case PPC::SETRNDi: {
14620 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14624 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14626 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14637 unsigned Mode =
MI.getOperand(1).getImm();
14638 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14642 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14647 case PPC::SETRND: {
14655 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14656 if (Subtarget.hasDirectMove()) {
14657 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14661 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14664 if (RC == &PPC::F8RCRegClass) {
14666 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14667 "Unsupported RegClass.");
14669 StoreOp = PPC::STFD;
14673 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14674 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14675 "Unsupported RegClass.");
14708 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14711 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14723 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14725 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14727 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14728 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14733 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14734 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14739 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14740 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14746 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14747 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14758 case PPC::SETFLM: {
14762 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14764 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14766 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14769 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14777 case PPC::PROBED_ALLOCA_32:
14778 case PPC::PROBED_ALLOCA_64:
14781 case PPC::SPLIT_QUADWORD: {
14788 .
addUse(Src, {}, PPC::sub_gp8_x1);
14791 .
addUse(Src, {}, PPC::sub_gp8_x0);
14794 case PPC::LQX_PSEUDO:
14795 case PPC::STQX_PSEUDO: {
14801 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14807 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14808 :
TII->get(PPC::STQ))
14814 case PPC::LWAT_PSEUDO:
14815 case PPC::LDAT_PSEUDO: {
14817 Register DstReg =
MI.getOperand(0).getReg();
14818 Register PtrReg =
MI.getOperand(1).getReg();
14819 Register ValReg =
MI.getOperand(2).getReg();
14820 unsigned FC =
MI.getOperand(3).getImm();
14821 bool IsLwat =
MI.getOpcode() == PPC::LWAT_PSEUDO;
14824 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
14832 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
14835 .
addImm(PPC::sub_gp8_x0)
14837 .
addImm(PPC::sub_gp8_x1);
14840 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
14846 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14849 .
addReg(Result64, {}, PPC::sub_32);
14855 case PPC::LWAT_COND_PSEUDO:
14856 case PPC::LDAT_COND_PSEUDO: {
14858 Register DstReg =
MI.getOperand(0).getReg();
14859 Register PtrReg =
MI.getOperand(1).getReg();
14860 unsigned FC =
MI.getOperand(2).getImm();
14861 bool IsLwat_Cond =
MI.getOpcode() == PPC::LWAT_COND_PSEUDO;
14864 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), Pair);
14867 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat_Cond ? PPC::LWAT : PPC::LDAT),
14874 .
addReg(PairResult, {}, PPC::sub_gp8_x0);
14877 .
addReg(Result64, {}, PPC::sub_32);
14887 MI.eraseFromParent();
14900 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14903 return RefinementSteps;
14910 EVT VT =
Op.getValueType();
14913 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14937PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14940 EVT VT =
Op.getValueType();
14941 if (VT != MVT::f64 &&
14942 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14945 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14949 int Enabled,
int &RefinementSteps,
14950 bool &UseOneConstNR,
14951 bool Reciprocal)
const {
14953 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14954 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14955 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14956 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14962 UseOneConstNR = !Subtarget.needsTwoConstNR();
14963 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14970 int &RefinementSteps)
const {
14972 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14973 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14974 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14975 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14978 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14994 switch (Subtarget.getCPUDirective()) {
15021 unsigned Bytes,
int Dist,
15035 if (FS != BFS || FS != (
int)Bytes)
return false;
15040 int64_t Offset1 = 0, Offset2 = 0;
15043 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15053 if (isGA1 && isGA2 && GV1 == GV2)
15054 return Offset1 == (Offset2 + Dist*Bytes);
15061 unsigned Bytes,
int Dist,
15064 EVT VT = LS->getMemoryVT();
15071 switch (
N->getConstantOperandVal(1)) {
15072 default:
return false;
15073 case Intrinsic::ppc_altivec_lvx:
15074 case Intrinsic::ppc_altivec_lvxl:
15075 case Intrinsic::ppc_vsx_lxvw4x:
15076 case Intrinsic::ppc_vsx_lxvw4x_be:
15079 case Intrinsic::ppc_vsx_lxvd2x:
15080 case Intrinsic::ppc_vsx_lxvd2x_be:
15083 case Intrinsic::ppc_altivec_lvebx:
15086 case Intrinsic::ppc_altivec_lvehx:
15089 case Intrinsic::ppc_altivec_lvewx:
15099 switch (
N->getConstantOperandVal(1)) {
15100 default:
return false;
15101 case Intrinsic::ppc_altivec_stvx:
15102 case Intrinsic::ppc_altivec_stvxl:
15103 case Intrinsic::ppc_vsx_stxvw4x:
15106 case Intrinsic::ppc_vsx_stxvd2x:
15109 case Intrinsic::ppc_vsx_stxvw4x_be:
15112 case Intrinsic::ppc_vsx_stxvd2x_be:
15115 case Intrinsic::ppc_altivec_stvebx:
15118 case Intrinsic::ppc_altivec_stvehx:
15121 case Intrinsic::ppc_altivec_stvewx:
15138 SDValue Chain = LD->getChain();
15139 EVT VT = LD->getMemoryVT();
15148 while (!Queue.empty()) {
15149 SDNode *ChainNext = Queue.pop_back_val();
15150 if (!Visited.
insert(ChainNext).second)
15157 if (!Visited.
count(ChainLD->getChain().getNode()))
15158 Queue.push_back(ChainLD->getChain().getNode());
15160 for (
const SDUse &O : ChainNext->
ops())
15161 if (!Visited.
count(O.getNode()))
15162 Queue.push_back(O.getNode());
15164 LoadRoots.
insert(ChainNext);
15175 for (
SDNode *
I : LoadRoots) {
15176 Queue.push_back(
I);
15178 while (!Queue.empty()) {
15179 SDNode *LoadRoot = Queue.pop_back_val();
15180 if (!Visited.
insert(LoadRoot).second)
15192 Queue.push_back(U);
15225 auto Final = Shifted;
15236 DAGCombinerInfo &DCI)
const {
15239 SelectionDAG &DAG = DCI.DAG;
15244 if (!DCI.isAfterLegalizeDAG())
15249 for (
const SDNode *U :
N->users())
15254 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15258 if (OpSize <
Size) {
15276 DAGCombinerInfo &DCI)
const {
15277 SelectionDAG &DAG = DCI.DAG;
15280 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15291 N->getValueType(0) != MVT::i1)
15294 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15295 N->getOperand(0).getValueType() != MVT::i64)
15305 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15316 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15339 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15340 N->getOperand(0).getOpcode() !=
ISD::OR &&
15341 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15351 N->getOperand(1).getOpcode() !=
ISD::AND &&
15352 N->getOperand(1).getOpcode() !=
ISD::OR &&
15353 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15364 SmallPtrSet<SDNode *, 16> Visited;
15366 for (
unsigned i = 0; i < 2; ++i) {
15370 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15382 while (!BinOps.
empty()) {
15390 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15424 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15428 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15429 if (User !=
N && !Visited.
count(User))
15438 if (
User->getOperand(0) == Inputs[i])
15441 if (
User->getOperand(0) == Inputs[i] ||
15442 User->getOperand(1) == Inputs[i])
15448 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15449 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15450 if (User !=
N && !Visited.
count(User))
15459 if (
User->getOperand(0) == PromOps[i])
15462 if (
User->getOperand(0) == PromOps[i] ||
15463 User->getOperand(1) == PromOps[i])
15470 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15479 std::list<HandleSDNode> PromOpHandles;
15480 for (
auto &PromOp : PromOps)
15481 PromOpHandles.emplace_back(PromOp);
15488 while (!PromOpHandles.empty()) {
15489 SDValue PromOp = PromOpHandles.back().getValue();
15490 PromOpHandles.pop_back();
15499 PromOpHandles.emplace_front(PromOp);
15513 default:
C = 0;
break;
15526 PromOpHandles.emplace_front(PromOp);
15533 for (
unsigned i = 0; i < 2; ++i)
15543 return N->getOperand(0);
15551 DAGCombinerInfo &DCI)
const {
15552 SelectionDAG &DAG = DCI.DAG;
15569 if (
N->getValueType(0) != MVT::i32 &&
15570 N->getValueType(0) != MVT::i64)
15573 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15574 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15577 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15578 N->getOperand(0).getOpcode() !=
ISD::OR &&
15579 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15586 SmallPtrSet<SDNode *, 16> Visited;
15590 while (!BinOps.
empty()) {
15598 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15624 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15629 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15634 if (User !=
N && !Visited.
count(User))
15640 if (
User->getOperand(0) == Inputs[i])
15641 SelectTruncOp[0].
insert(std::make_pair(User,
15642 User->getOperand(0).getValueType()));
15644 if (
User->getOperand(0) == Inputs[i])
15645 SelectTruncOp[0].
insert(std::make_pair(User,
15646 User->getOperand(0).getValueType()));
15647 if (
User->getOperand(1) == Inputs[i])
15648 SelectTruncOp[1].
insert(std::make_pair(User,
15649 User->getOperand(1).getValueType()));
15654 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15656 if (User !=
N && !Visited.
count(User))
15662 if (
User->getOperand(0) == PromOps[i])
15663 SelectTruncOp[0].
insert(std::make_pair(User,
15664 User->getOperand(0).getValueType()));
15666 if (
User->getOperand(0) == PromOps[i])
15667 SelectTruncOp[0].
insert(std::make_pair(User,
15668 User->getOperand(0).getValueType()));
15669 if (
User->getOperand(1) == PromOps[i])
15670 SelectTruncOp[1].
insert(std::make_pair(User,
15671 User->getOperand(1).getValueType()));
15676 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15677 bool ReallyNeedsExt =
false;
15681 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15686 Inputs[i].getOperand(0).getValueSizeInBits();
15687 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15692 OpBits-PromBits))) ||
15695 (OpBits-(PromBits-1)))) {
15696 ReallyNeedsExt =
true;
15704 std::list<HandleSDNode> PromOpHandles;
15705 for (
auto &PromOp : PromOps)
15706 PromOpHandles.emplace_back(PromOp);
15710 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15717 SDValue InSrc = Inputs[i].getOperand(0);
15735 while (!PromOpHandles.empty()) {
15737 PromOpHandles.pop_back();
15741 default:
C = 0;
break;
15754 PromOpHandles.emplace_front(PromOp);
15764 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15766 PromOpHandles.emplace_front(PromOp);
15774 for (
unsigned i = 0; i < 2; ++i) {
15792 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15793 if (SI0 != SelectTruncOp[0].
end())
15795 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15796 if (SI1 != SelectTruncOp[1].
end())
15805 if (!ReallyNeedsExt)
15806 return N->getOperand(0);
15813 N->getValueSizeInBits(0), PromBits),
15814 dl,
N->getValueType(0)));
15817 "Invalid extension type");
15820 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15830 auto isValidForConvert = [](
SDValue &Operand) {
15849 if (LoadNode->isVolatile())
15870 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15880 "CC mus be ISD::SETNE or ISD::SETEQ");
15882 auto getV16i8Load = [&](
const SDValue &Operand) {
15890 DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15891 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15932 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15933 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15936 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15939 IntrID, CRSel, LHSVec, RHSVec);
15942 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15960 auto IsAndWithOne = [](
SDValue &V) {
15971 auto IsCompareWithZero = [](
SDValue &V) {
15978 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15979 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15996 auto MakeXor1 = [&](
SDValue V) {
15997 EVT VT = V.getValueType();
16004 return MakeXor1(
LHS);
16007 return MakeXor1(
RHS);
16024 DAGCombinerInfo &DCI)
const {
16025 if (Subtarget.isISA3_1())
16028 EVT VT =
N->getValueType(0);
16029 if (VT != MVT::i32 && VT != MVT::i64)
16045 SelectionDAG &DAG = DCI.DAG;
16047 EVT XVT =
X.getValueType();
16049 if ((XVT == MVT::i64 || VT == MVT::i64) && !Subtarget.isPPC64())
16055 if (XVT != MVT::i64 && Subtarget.isPPC64())
16059 EVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16067 Addc, Addc, Carry);
16070 if (OpVT == MVT::i64 && VT == MVT::i32)
16077 DAGCombinerInfo &DCI)
const {
16079 "Should be called with a SETCC node");
16101 SelectionDAG &DAG = DCI.DAG;
16102 EVT VT =
N->getValueType(0);
16103 EVT OpVT =
LHS.getValueType();
16125 return DAGCombineTruncBoolExt(
N, DCI);
16132 Op.getValueType() == MVT::f64;
16144combineElementTruncationToVectorTruncation(
SDNode *
N,
16145 DAGCombinerInfo &DCI)
const {
16147 "Should be called with a BUILD_VECTOR node");
16149 SelectionDAG &DAG = DCI.DAG;
16152 SDValue FirstInput =
N->getOperand(0);
16154 "The input operand must be an fp-to-int conversion.");
16159 if (FirstConversion == PPCISD::FCTIDZ ||
16160 FirstConversion == PPCISD::FCTIDUZ ||
16161 FirstConversion == PPCISD::FCTIWZ ||
16162 FirstConversion == PPCISD::FCTIWUZ) {
16163 bool IsSplat =
true;
16164 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16165 FirstConversion == PPCISD::FCTIWUZ;
16168 EVT TargetVT =
N->getValueType(0);
16169 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16170 SDValue NextOp =
N->getOperand(i);
16171 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16174 if (NextConversion != FirstConversion)
16182 if (
N->getOperand(i) != FirstInput)
16193 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16194 SDValue In =
N->getOperand(i).getOperand(0);
16204 Ops.push_back(Trunc);
16207 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16211 if (FirstConversion == PPCISD::FCTIDZ ||
16212 FirstConversion == PPCISD::FCTIWZ)
16217 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16219 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16237 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16241 if (FullVal == BasePattern)
16242 return std::make_tuple(Uim,
uint8_t{0});
16245 if (FullVal ==
APInt(128, 1))
16246 return std::make_tuple(Uim,
uint8_t{127});
16248 return std::nullopt;
16268 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16272 EVT VT =
Op.getValueType();
16273 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16287 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16297 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16301 uint64_t ElemValue =
C->getZExtValue();
16305 ElemValue &= ((1ULL << ElemBits) - 1);
16309 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16312 APInt ElemAPInt(128, ElemValue);
16313 ElemAPInt <<= BitPos;
16316 FullVal |= ElemAPInt;
16323 const auto &[Uim, ShiftAmount] = *UIMOpt;
16327 if (ShiftAmount == 0) {
16332 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16333 LxvkqInstr.
dump());
16337 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16349 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16352 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16368 "Should be called with a BUILD_VECTOR node");
16373 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16376 bool InputsAreConsecutiveLoads =
true;
16377 bool InputsAreReverseConsecutive =
true;
16378 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16379 SDValue FirstInput =
N->getOperand(0);
16380 bool IsRoundOfExtLoad =
false;
16390 N->getNumOperands() == 1)
16393 if (!IsRoundOfExtLoad)
16398 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16400 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16403 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16409 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16420 InputsAreConsecutiveLoads =
false;
16422 InputsAreReverseConsecutive =
false;
16425 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16430 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16431 "The loads cannot be both consecutive and reverse consecutive.");
16435 if (InputsAreConsecutiveLoads) {
16436 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16440 ReturnSDVal = WideLoad;
16441 }
else if (InputsAreReverseConsecutive) {
16443 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16448 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16456 for (
auto *LD : InputLoads)
16458 return ReturnSDVal;
16469 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16475 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16477 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16479 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16480 CorrectElems = CorrectElems >> 8;
16481 Elems = Elems >> 8;
16488 EVT VT =
N->getValueType(0);
16492 Input.getValueType().getVectorElementType(),
16526 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16552 Elems = Elems << 8;
16561 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16562 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16569 int TgtElemArrayIdx;
16570 int InputSize =
Input.getValueType().getScalarSizeInBits();
16571 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16572 if (InputSize + OutputSize == 40)
16573 TgtElemArrayIdx = 0;
16574 else if (InputSize + OutputSize == 72)
16575 TgtElemArrayIdx = 1;
16576 else if (InputSize + OutputSize == 48)
16577 TgtElemArrayIdx = 2;
16578 else if (InputSize + OutputSize == 80)
16579 TgtElemArrayIdx = 3;
16580 else if (InputSize + OutputSize == 96)
16581 TgtElemArrayIdx = 4;
16585 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16587 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16588 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16589 if (Elems != CorrectElems) {
16605 if (
N->getValueType(0) != MVT::v1i128)
16608 SDValue Operand =
N->getOperand(0);
16615 EVT MemoryType = LD->getMemoryVT();
16619 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16620 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16623 if (!ValidLDType ||
16629 LD->getChain(), LD->getBasePtr(),
16633 DAG.
getVTList(MVT::v1i128, MVT::Other),
16634 LoadOps, MemoryType, LD->getMemOperand());
16638 DAGCombinerInfo &DCI)
const {
16640 "Should be called with a BUILD_VECTOR node");
16642 SelectionDAG &DAG = DCI.DAG;
16645 if (!Subtarget.hasVSX())
16652 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16653 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16668 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16677 if (Subtarget.isISA3_1()) {
16683 if (
N->getValueType(0) != MVT::v2f64)
16694 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16705 if (!Ext1Op || !Ext2Op)
16714 if (FirstElem == 0 && SecondElem == 1)
16715 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16716 else if (FirstElem == 2 && SecondElem == 3)
16717 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16723 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16724 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16729 DAGCombinerInfo &DCI)
const {
16732 "Need an int -> FP conversion node here");
16737 SelectionDAG &DAG = DCI.DAG;
16743 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16745 if (!
Op.getOperand(0).getValueType().isSimple())
16747 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16748 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16751 SDValue FirstOperand(
Op.getOperand(0));
16752 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16753 (FirstOperand.getValueType() == MVT::i8 ||
16754 FirstOperand.getValueType() == MVT::i16);
16755 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16757 bool DstDouble =
Op.getValueType() == MVT::f64;
16758 unsigned ConvOp =
Signed ?
16759 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16760 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16765 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16768 Ops, MVT::i8, LDN->getMemOperand());
16773 SDValue ExtOps[] = { Ld, WidthConst };
16775 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16777 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16785 if (
Op.getOperand(0).getValueType() == MVT::i32)
16789 "UINT_TO_FP is supported only with FPCVT");
16793 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16798 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16805 Subtarget.hasFPCVT()) ||
16807 SDValue Src =
Op.getOperand(0).getOperand(0);
16808 if (Src.getValueType() == MVT::f32) {
16810 DCI.AddToWorklist(Src.getNode());
16811 }
else if (Src.getValueType() != MVT::f64) {
16823 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16826 DCI.AddToWorklist(
FP.getNode());
16850 switch (
N->getOpcode()) {
16855 Chain = LD->getChain();
16856 Base = LD->getBasePtr();
16857 MMO = LD->getMemOperand();
16876 MVT VecTy =
N->getValueType(0).getSimpleVT();
16884 Chain = Load.getValue(1);
16886 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16890 if (VecTy != MVT::v2f64) {
16917 switch (
N->getOpcode()) {
16922 Chain = ST->getChain();
16923 Base = ST->getBasePtr();
16924 MMO = ST->getMemOperand();
16944 SDValue Src =
N->getOperand(SrcOpnd);
16945 MVT VecTy = Src.getValueType().getSimpleVT();
16948 if (VecTy != MVT::v2f64) {
16954 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16960 StoreOps, VecTy, MMO);
16967 DAGCombinerInfo &DCI)
const {
16970 unsigned Opcode =
N->getOperand(1).getOpcode();
16972 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16976 &&
"Not a FP_TO_INT Instruction!");
16978 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16979 EVT Op1VT =
N->getOperand(1).getValueType();
16982 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16986 bool ValidTypeForStoreFltAsInt =
16987 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16988 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16991 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16994 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
17002 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
17017 bool PrevElemFromFirstVec = Mask[0] < NumElts;
17018 for (
int i = 1, e = Mask.size(); i < e; i++) {
17019 if (PrevElemFromFirstVec && Mask[i] < NumElts)
17021 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
17023 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17034 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17035 FirstOp =
Op.getOperand(i);
17041 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17042 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17052 Op =
Op.getOperand(0);
17068 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17069 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
17071 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17073 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17074 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17075 int Idx = ShuffV[
I];
17076 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17077 ShuffV[
I] += LHSEltFixup;
17078 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17079 ShuffV[
I] += RHSEltFixup;
17090 SDLoc dl(OrigSToV);
17093 "Expecting a SCALAR_TO_VECTOR here");
17106 "Cannot produce a permuted scalar_to_vector for one element vector");
17108 unsigned ResultInElt = NumElts / 2;
17114 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17119 int HalfVec,
int LHSLastElementDefined,
17120 int RHSLastElementDefined) {
17121 for (
int Index : ShuffV) {
17125 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17126 (Index > LHSLastElementDefined))
17129 if ((RHSLastElementDefined >= 0) &&
17130 (Index > HalfVec + RHSLastElementDefined))
17137 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17138 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17154 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17155 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17158 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17159 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17160 return SToVPermuted;
17180 int NumElts =
LHS.getValueType().getVectorNumElements();
17183 bool IsLittleEndian = Subtarget.isLittleEndian();
17190 if (!Subtarget.hasDirectMove())
17210 SmallVector<int, 16> ShuffV(Mask);
17213 if (SToVLHS || SToVRHS) {
17216 int ShuffleNumElts = ShuffV.
size();
17217 int HalfVec = ShuffleNumElts / 2;
17223 unsigned LHSNumValidElts = HalfVec;
17224 unsigned RHSNumValidElts = HalfVec;
17229 int LHSFirstElt = 0;
17230 int RHSFirstElt = ShuffleNumElts;
17231 int LHSLastElt = -1;
17232 int RHSLastElt = -1;
17240 int LHSScalarSize = 0;
17241 int RHSScalarSize = 0;
17244 if (!IsLittleEndian && LHSScalarSize >= 64)
17249 if (!IsLittleEndian && RHSScalarSize >= 64)
17252 if (LHSScalarSize != 0)
17254 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17255 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17256 if (RHSScalarSize != 0)
17258 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17259 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17270 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17271 LHSNumValidElts, RHSNumValidElts, Subtarget);
17297 if (IsLittleEndian) {
17300 if (Mask[0] < NumElts)
17301 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17305 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17310 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17314 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17319 if (Mask[0] < NumElts)
17320 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17324 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17329 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17333 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17343 if (IsLittleEndian)
17352 DAGCombinerInfo &DCI)
const {
17354 "Not a reverse memop pattern!");
17356 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17359 auto I =
Mask.rbegin();
17360 auto E =
Mask.rend();
17362 for (;
I !=
E; ++
I) {
17370 SelectionDAG &DAG = DCI.DAG;
17373 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17379 if (!Subtarget.hasP9Vector())
17382 if(!IsElementReverse(SVN))
17389 for (SDUse &Use : LSBase->
uses())
17390 if (
Use.getResNo() == 0 &&
17397 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17412 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17421 if (IntrinsicID == Intrinsic::ppc_stdcx)
17423 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17425 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17427 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17436 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17440 if (
LHS->getOpcode() == PPCISD::ADDE &&
17460 SDValue CmpLHS =
N->getOperand(0);
17461 SDValue CmpRHS =
N->getOperand(1);
17462 SDValue TrueVal =
N->getOperand(2);
17463 SDValue FalseVal =
N->getOperand(3);
17477 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17480 SDValue ShiftVal = FalseVal.getOperand(0);
17481 SDValue ShiftAmt = FalseVal.getOperand(1);
17485 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17512 if (CtlzArg != CmpLHS)
17520 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17567 auto isZeroOrOne = [=](
SDValue &V) {
17569 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17574 if (!isZeroOrOne(NonNullConstant))
17584 EVT VType =
N->getValueType(0);
17588 return NewNonNullConstant;
17607 EVT XorVT =
N->getValueType(0);
17608 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17616 if (!XorConst || !XorConst->
isOne()) {
17618 if (!XorConst || !XorConst->
isOne())
17625 if (!
LHS.hasOneUse())
17633 SelectNode =
LHS.getOperand(0);
17647 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17657 if (!ConstOp1 || !ConstOp2)
17661 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17670 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17672 bool ConstOp1IsOne = ConstOp1->
isOne();
17675 {SelectNode.getOperand(0),
17676 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17677 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17678 SelectNode.getOperand(3)}),
17686 switch (
N->getOpcode()) {
17689 return combineADD(
N, DCI);
17721 return combineSHL(
N, DCI);
17723 return combineSRA(
N, DCI);
17725 return combineSRL(
N, DCI);
17727 return combineMUL(
N, DCI);
17729 case PPCISD::FNMSUB:
17730 return combineFMALike(
N, DCI);
17733 return N->getOperand(0);
17737 return N->getOperand(0);
17743 return N->getOperand(0);
17747 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
17755 return DAGCombineExtBoolTrunc(
N, DCI);
17757 return combineTRUNCATE(
N, DCI);
17759 if (
SDValue CSCC = combineSetCC(
N, DCI))
17765 return DAGCombineTruncBoolExt(
N, DCI);
17768 return combineFPToIntToFP(
N, DCI);
17777 EVT Op1VT =
N->getOperand(1).getValueType();
17778 unsigned Opcode =
N->getOperand(1).getOpcode();
17782 SDValue Val = combineStoreFPToInt(
N, DCI);
17796 N->getOperand(1).getNode()->hasOneUse() &&
17797 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17798 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17806 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17813 if (Op1VT.
bitsGT(mVT)) {
17818 if (Op1VT == MVT::i64)
17823 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17843 ST->getBasePtr(), ST->getOffset(), MemVT,
17844 ST->getMemOperand(), ST->getAddressingMode(),
17848 return ST->isUnindexed()
17857 if (Subtarget.needsSwapsForVSXMemOps() &&
17858 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17859 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17866 EVT VT = LD->getValueType(0);
17872 if (Subtarget.needsSwapsForVSXMemOps() &&
17873 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17874 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17885 auto ReplaceTwoFloatLoad = [&]() {
17886 if (VT != MVT::i64)
17901 if (!LD->hasNUsesOfValue(2, 0))
17904 auto UI = LD->user_begin();
17905 while (UI.getUse().getResNo() != 0) ++UI;
17907 while (UI.getUse().getResNo() != 0) ++UI;
17908 SDNode *RightShift = *UI;
17916 if (RightShift->getOpcode() !=
ISD::SRL ||
17918 RightShift->getConstantOperandVal(1) != 32 ||
17919 !RightShift->hasOneUse())
17922 SDNode *Trunc2 = *RightShift->user_begin();
17932 Bitcast->getValueType(0) != MVT::f32)
17938 if (Subtarget.isLittleEndian())
17944 SDValue BasePtr = LD->getBasePtr();
17945 if (LD->isIndexed()) {
17947 "Non-pre-inc AM on PPC?");
17955 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17956 LD->getPointerInfo(), LD->getAlign(),
17957 MMOFlags, LD->getAAInfo());
17963 LD->getPointerInfo().getWithOffset(4),
17966 if (LD->isIndexed()) {
17980 if (ReplaceTwoFloatLoad())
17983 EVT MemVT = LD->getMemoryVT();
17986 if (LD->isUnindexed() && VT.
isVector() &&
17989 !Subtarget.hasP8Vector() &&
17990 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17991 VT == MVT::v4f32))) &&
17992 LD->getAlign() < ABIAlignment) {
17994 SDValue Chain = LD->getChain();
17995 SDValue Ptr = LD->getBasePtr();
17996 bool isLittleEndian = Subtarget.isLittleEndian();
18023 MVT PermCntlTy, PermTy, LDTy;
18024 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18025 : Intrinsic::ppc_altivec_lvsl;
18026 IntrLD = Intrinsic::ppc_altivec_lvx;
18027 IntrPerm = Intrinsic::ppc_altivec_vperm;
18028 PermCntlTy = MVT::v16i8;
18029 PermTy = MVT::v4i32;
18048 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18052 BaseLoadOps, LDTy, BaseMMO);
18061 int IncValue = IncOffset;
18078 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18082 ExtraLoadOps, LDTy, ExtraMMO);
18093 if (isLittleEndian)
18095 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18098 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18101 Perm = Subtarget.hasAltivec()
18116 bool isLittleEndian = Subtarget.isLittleEndian();
18117 unsigned IID =
N->getConstantOperandVal(0);
18118 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18119 : Intrinsic::ppc_altivec_lvsl);
18120 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18127 .zext(
Add.getScalarValueSizeInBits()))) {
18128 SDNode *BasePtr =
Add->getOperand(0).getNode();
18129 for (
SDNode *U : BasePtr->users()) {
18131 U->getConstantOperandVal(0) == IID) {
18142 SDNode *BasePtr =
Add->getOperand(0).getNode();
18143 for (
SDNode *U : BasePtr->users()) {
18146 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18152 V->getConstantOperandVal(0) == IID) {
18164 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18165 IID == Intrinsic::ppc_altivec_vmaxsh ||
18166 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18197 switch (
N->getConstantOperandVal(1)) {
18200 case Intrinsic::ppc_altivec_vsum4sbs:
18201 case Intrinsic::ppc_altivec_vsum4shs:
18202 case Intrinsic::ppc_altivec_vsum4ubs: {
18209 APInt APSplatBits, APSplatUndef;
18210 unsigned SplatBitSize;
18213 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18214 !Subtarget.isLittleEndian());
18216 if (BVNIsConstantSplat && APSplatBits == 0)
18221 case Intrinsic::ppc_vsx_lxvw4x:
18222 case Intrinsic::ppc_vsx_lxvd2x:
18225 if (Subtarget.needsSwapsForVSXMemOps())
18233 if (Subtarget.needsSwapsForVSXMemOps()) {
18234 switch (
N->getConstantOperandVal(1)) {
18237 case Intrinsic::ppc_vsx_stxvw4x:
18238 case Intrinsic::ppc_vsx_stxvd2x:
18247 bool Is64BitBswapOn64BitTgt =
18248 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18250 N->getOperand(0).hasOneUse();
18251 if (IsSingleUseNormalLd &&
18252 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18253 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18264 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18265 MVT::i64 : MVT::i32, MVT::Other),
18266 Ops, LD->getMemoryVT(), LD->getMemOperand());
18270 if (
N->getValueType(0) == MVT::i16)
18287 !IsSingleUseNormalLd)
18292 if (!LD->isSimple())
18294 SDValue BasePtr = LD->getBasePtr();
18296 LD->getPointerInfo(), LD->getAlign());
18301 LD->getMemOperand(), 4, 4);
18305 if (Subtarget.isLittleEndian())
18311 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18320 if (!
N->getOperand(0).hasOneUse() &&
18321 !
N->getOperand(1).hasOneUse() &&
18322 !
N->getOperand(2).hasOneUse()) {
18325 SDNode *VCMPrecNode =
nullptr;
18327 SDNode *LHSN =
N->getOperand(0).getNode();
18329 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18333 VCMPrecNode =
User;
18345 SDNode *FlagUser =
nullptr;
18347 FlagUser ==
nullptr; ++UI) {
18348 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18361 return SDValue(VCMPrecNode, 0);
18372 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18383 auto RHSAPInt = RHS->getAsAPIntVal();
18384 if (!RHSAPInt.isIntN(64))
18387 unsigned Val = RHSAPInt.getZExtValue();
18388 auto isImpossibleCompare = [&]() {
18391 if (Val != 0 && Val != 1) {
18393 return N->getOperand(0);
18396 N->getOperand(0),
N->getOperand(4));
18401 unsigned StoreWidth = 0;
18404 if (
SDValue Impossible = isImpossibleCompare())
18416 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18420 PPCISD::STORE_COND, dl,
18422 MemNode->getMemoryVT(), MemNode->getMemOperand());
18426 if (
N->getOperand(0) == LHS.getValue(1))
18437 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18439 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18445 assert(isDot &&
"Can't compare against a vector result!");
18447 if (
SDValue Impossible = isImpossibleCompare())
18450 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18457 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18462 switch (LHS.getConstantOperandVal(1)) {
18478 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18481 N->getOperand(4), CompNode.
getValue(1));
18486 return DAGCombineBuildVector(
N, DCI);
18491 return DAGCombineBitcast(
N, DCI);
18502 EVT VT =
N->getValueType(0);
18503 if (VT == MVT::i64 && !Subtarget.isPPC64())
18505 if ((VT != MVT::i32 && VT != MVT::i64) ||
18513 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18533 const APInt &DemandedElts,
18535 unsigned Depth)
const {
18537 switch (
Op.getOpcode()) {
18539 case PPCISD::LBRX: {
18542 Known.
Zero = 0xFFFF0000;
18545 case PPCISD::ADDE: {
18546 if (
Op.getResNo() == 0) {
18551 Known.
Zero = ~1ULL;
18556 switch (
Op.getConstantOperandVal(0)) {
18558 case Intrinsic::ppc_altivec_vcmpbfp_p:
18559 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18560 case Intrinsic::ppc_altivec_vcmpequb_p:
18561 case Intrinsic::ppc_altivec_vcmpequh_p:
18562 case Intrinsic::ppc_altivec_vcmpequw_p:
18563 case Intrinsic::ppc_altivec_vcmpequd_p:
18564 case Intrinsic::ppc_altivec_vcmpequq_p:
18565 case Intrinsic::ppc_altivec_vcmpgefp_p:
18566 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18567 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18568 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18569 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18570 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18571 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18572 case Intrinsic::ppc_altivec_vcmpgtub_p:
18573 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18574 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18575 case Intrinsic::ppc_altivec_vcmpgtud_p:
18576 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18583 switch (
Op.getConstantOperandVal(1)) {
18586 case Intrinsic::ppc_load2r:
18588 Known.
Zero = 0xFFFF0000;
18597 switch (Subtarget.getCPUDirective()) {
18619 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18628 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18630 LoopSize +=
TII->getInstSizeInBytes(J);
18635 if (LoopSize > 16 && LoopSize <= 32)
18649 if (Constraint.
size() == 1) {
18650 switch (Constraint[0]) {
18668 }
else if (Constraint ==
"wc") {
18670 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18671 Constraint ==
"wf" || Constraint ==
"ws" ||
18672 Constraint ==
"wi" || Constraint ==
"ww") {
18685 Value *CallOperandVal =
info.CallOperandVal;
18688 if (!CallOperandVal)
18695 else if ((
StringRef(constraint) ==
"wa" ||
18707 switch (*constraint) {
18737std::pair<unsigned, const TargetRegisterClass *>
18741 if (Constraint.
size() == 1) {
18743 switch (Constraint[0]) {
18745 if (VT == MVT::i64 && Subtarget.isPPC64())
18746 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18747 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18749 if (VT == MVT::i64 && Subtarget.isPPC64())
18750 return std::make_pair(0U, &PPC::G8RCRegClass);
18751 return std::make_pair(0U, &PPC::GPRCRegClass);
18757 if (Subtarget.hasSPE()) {
18758 if (VT == MVT::f32 || VT == MVT::i32)
18759 return std::make_pair(0U, &PPC::GPRCRegClass);
18760 if (VT == MVT::f64 || VT == MVT::i64)
18761 return std::make_pair(0U, &PPC::SPERCRegClass);
18763 if (VT == MVT::f32 || VT == MVT::i32)
18764 return std::make_pair(0U, &PPC::F4RCRegClass);
18765 if (VT == MVT::f64 || VT == MVT::i64)
18766 return std::make_pair(0U, &PPC::F8RCRegClass);
18770 if (Subtarget.hasAltivec() && VT.
isVector())
18771 return std::make_pair(0U, &PPC::VRRCRegClass);
18772 else if (Subtarget.hasVSX())
18774 return std::make_pair(0U, &PPC::VFRCRegClass);
18777 return std::make_pair(0U, &PPC::CRRCRegClass);
18779 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18781 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18782 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18783 Constraint ==
"wf" || Constraint ==
"wi") &&
18784 Subtarget.hasVSX()) {
18788 return std::make_pair(0U, &PPC::VSRCRegClass);
18789 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18790 return std::make_pair(0U, &PPC::VSSRCRegClass);
18791 return std::make_pair(0U, &PPC::VSFRCRegClass);
18792 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18793 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18794 return std::make_pair(0U, &PPC::VSSRCRegClass);
18796 return std::make_pair(0U, &PPC::VSFRCRegClass);
18797 }
else if (Constraint ==
"lr") {
18798 if (VT == MVT::i64)
18799 return std::make_pair(0U, &PPC::LR8RCRegClass);
18801 return std::make_pair(0U, &PPC::LRRCRegClass);
18806 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18810 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18811 int VSNum = atoi(Constraint.
data() + 3);
18812 assert(VSNum >= 0 && VSNum <= 63 &&
18813 "Attempted to access a vsr out of range");
18815 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18816 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18821 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18822 int RegNum = atoi(Constraint.
data() + 2);
18823 if (RegNum > 31 || RegNum < 0)
18825 if (VT == MVT::f32 || VT == MVT::i32)
18826 return Subtarget.hasSPE()
18827 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18828 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18829 if (VT == MVT::f64 || VT == MVT::i64)
18830 return Subtarget.hasSPE()
18831 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18832 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18836 std::pair<unsigned, const TargetRegisterClass *> R =
18845 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18846 PPC::GPRCRegClass.contains(R.first))
18847 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18848 PPC::sub_32, &PPC::G8RCRegClass),
18849 &PPC::G8RCRegClass);
18852 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18853 R.first = PPC::CR0;
18854 R.second = &PPC::CRRCRegClass;
18858 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18859 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18860 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18861 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18862 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18863 "default AIX AltiVec ABI and cannot be used\n";
18873 std::vector<SDValue> &
Ops,
18878 if (Constraint.
size() > 1)
18881 char Letter = Constraint[0];
18896 EVT TCVT = MVT::i64;
18937 if (Result.getNode()) {
18938 Ops.push_back(Result);
18949 if (
I.getNumOperands() <= 1)
18953 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18954 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18955 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18958 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18974 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18986 switch (AM.
Scale) {
19014 unsigned Depth =
Op.getConstantOperandVal(0);
19038 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19046 unsigned Depth =
Op.getConstantOperandVal(0);
19053 bool isPPC64 = PtrVT == MVT::i64;
19059 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19061 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19067 FrameAddr, MachinePointerInfo());
19071#define GET_REGISTER_MATCHER
19072#include "PPCGenAsmMatcher.inc"
19076 bool IsPPC64 = Subtarget.isPPC64();
19088 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19094 Reg = Reg.id() - PPC::R0 + PPC::X0;
19101 if (Subtarget.is32BitELFABI())
19106 if (Subtarget.isAIXABI())
19120 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19136 case Intrinsic::ppc_atomicrmw_xchg_i128:
19137 case Intrinsic::ppc_atomicrmw_add_i128:
19138 case Intrinsic::ppc_atomicrmw_sub_i128:
19139 case Intrinsic::ppc_atomicrmw_nand_i128:
19140 case Intrinsic::ppc_atomicrmw_and_i128:
19141 case Intrinsic::ppc_atomicrmw_or_i128:
19142 case Intrinsic::ppc_atomicrmw_xor_i128:
19143 case Intrinsic::ppc_cmpxchg_i128:
19145 Info.memVT = MVT::i128;
19146 Info.ptrVal =
I.getArgOperand(0);
19148 Info.align =
Align(16);
19153 case Intrinsic::ppc_atomic_load_i128:
19155 Info.memVT = MVT::i128;
19156 Info.ptrVal =
I.getArgOperand(0);
19158 Info.align =
Align(16);
19162 case Intrinsic::ppc_atomic_store_i128:
19164 Info.memVT = MVT::i128;
19165 Info.ptrVal =
I.getArgOperand(2);
19167 Info.align =
Align(16);
19171 case Intrinsic::ppc_altivec_lvx:
19172 case Intrinsic::ppc_altivec_lvxl:
19173 case Intrinsic::ppc_altivec_lvebx:
19174 case Intrinsic::ppc_altivec_lvehx:
19175 case Intrinsic::ppc_altivec_lvewx:
19176 case Intrinsic::ppc_vsx_lxvd2x:
19177 case Intrinsic::ppc_vsx_lxvw4x:
19178 case Intrinsic::ppc_vsx_lxvd2x_be:
19179 case Intrinsic::ppc_vsx_lxvw4x_be:
19180 case Intrinsic::ppc_vsx_lxvl:
19181 case Intrinsic::ppc_vsx_lxvll: {
19184 case Intrinsic::ppc_altivec_lvebx:
19187 case Intrinsic::ppc_altivec_lvehx:
19190 case Intrinsic::ppc_altivec_lvewx:
19193 case Intrinsic::ppc_vsx_lxvd2x:
19194 case Intrinsic::ppc_vsx_lxvd2x_be:
19204 Info.ptrVal =
I.getArgOperand(0);
19207 Info.align =
Align(1);
19212 case Intrinsic::ppc_altivec_stvx:
19213 case Intrinsic::ppc_altivec_stvxl:
19214 case Intrinsic::ppc_altivec_stvebx:
19215 case Intrinsic::ppc_altivec_stvehx:
19216 case Intrinsic::ppc_altivec_stvewx:
19217 case Intrinsic::ppc_vsx_stxvd2x:
19218 case Intrinsic::ppc_vsx_stxvw4x:
19219 case Intrinsic::ppc_vsx_stxvd2x_be:
19220 case Intrinsic::ppc_vsx_stxvw4x_be:
19221 case Intrinsic::ppc_vsx_stxvl:
19222 case Intrinsic::ppc_vsx_stxvll: {
19225 case Intrinsic::ppc_altivec_stvebx:
19228 case Intrinsic::ppc_altivec_stvehx:
19231 case Intrinsic::ppc_altivec_stvewx:
19234 case Intrinsic::ppc_vsx_stxvd2x:
19235 case Intrinsic::ppc_vsx_stxvd2x_be:
19245 Info.ptrVal =
I.getArgOperand(1);
19248 Info.align =
Align(1);
19253 case Intrinsic::ppc_stdcx:
19254 case Intrinsic::ppc_stwcx:
19255 case Intrinsic::ppc_sthcx:
19256 case Intrinsic::ppc_stbcx: {
19258 auto Alignment =
Align(8);
19260 case Intrinsic::ppc_stdcx:
19263 case Intrinsic::ppc_stwcx:
19265 Alignment =
Align(4);
19267 case Intrinsic::ppc_sthcx:
19269 Alignment =
Align(2);
19271 case Intrinsic::ppc_stbcx:
19273 Alignment =
Align(1);
19278 Info.ptrVal =
I.getArgOperand(0);
19280 Info.align = Alignment;
19294 const AttributeList &FuncAttributes)
const {
19298 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19299 if (
Op.isMemset() && Subtarget.hasVSX()) {
19304 if (TailSize > 2 && TailSize <= 4) {
19309 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19314 if (Subtarget.isPPC64()) {
19325 assert(Ty->isIntegerTy());
19327 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19328 return !(BitSize == 0 || BitSize > 64);
19336 return NumBits1 == 64 && NumBits2 == 32;
19344 return NumBits1 == 64 && NumBits2 == 32;
19351 EVT MemVT = LD->getMemoryVT();
19352 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19353 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19369 "invalid fpext types");
19371 if (DestVT == MVT::f128)
19386 unsigned *
Fast)
const {
19400 !Subtarget.allowsUnalignedFPAccess())
19404 if (Subtarget.hasVSX()) {
19405 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19406 VT != MVT::v4f32 && VT != MVT::v4i32)
19413 if (VT == MVT::ppcf128)
19428 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19436 int64_t Imm = ConstNode->getSExtValue();
19457 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19459 switch (Ty->getScalarType()->getTypeID()) {
19464 return Subtarget.hasP9Vector();
19472 if (!
I->hasOneUse())
19476 assert(
User &&
"A single use instruction with no uses.");
19478 switch (
I->getOpcode()) {
19479 case Instruction::FMul: {
19481 if (
User->getOpcode() != Instruction::FSub &&
19482 User->getOpcode() != Instruction::FAdd)
19489 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19490 User->getFastMathFlags().allowContract();
19496 case Instruction::Load: {
19509 if (
User->getOpcode() != Instruction::Store)
19529 static const MCPhysReg ScratchRegs[] = {
19530 PPC::X12, PPC::LR8, PPC::CTR8, 0
19533 return ScratchRegs;
19537 const Constant *PersonalityFn)
const {
19538 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19542 const Constant *PersonalityFn)
const {
19543 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19548 EVT VT ,
unsigned DefinedValues)
const {
19549 if (VT == MVT::v2i64)
19550 return Subtarget.hasDirectMove();
19552 if (Subtarget.hasVSX())
19579 return PPCISD::FNMSUB;
19580 case PPCISD::FNMSUB:
19586 bool LegalOps,
bool OptForSize,
19588 unsigned Depth)
const {
19592 unsigned Opc =
Op.getOpcode();
19593 EVT VT =
Op.getValueType();
19597 case PPCISD::FNMSUB:
19617 if (Flags.hasNoSignedZeros()) {
19621 N0Cost,
Depth + 1);
19625 N1Cost,
Depth + 1);
19627 if (NegN0 && N0Cost <= N1Cost) {
19628 Cost = std::min(N0Cost, N2Cost);
19630 }
else if (NegN1) {
19631 Cost = std::min(N1Cost, N2Cost);
19651 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19657 bool ForCodeSize)
const {
19658 if (!VT.
isSimple() || !Subtarget.hasVSX())
19668 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19673 APSInt IntResult(16,
false);
19678 if (IsExact && IntResult <= 15 && IntResult >= -16)
19680 return Imm.isZero();
19683 return Imm.isPosZero();
19695 unsigned Opcode =
N->getOpcode();
19715 if (Mask->getZExtValue() == OpSizeInBits - 1)
19722 DAGCombinerInfo &DCI)
const {
19723 EVT VT =
N->getValueType(0);
19726 unsigned Opc =
N->getOpcode();
19728 "Unexpected opcode.");
19735 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19739 uint64_t SplatBits = 0;
19740 bool AddSplatCase =
false;
19744 AddSplatCase =
true;
19748 if (!AddSplatCase) {
19752 unsigned SplatBitSize;
19754 APInt APSplatBits, APSplatUndef;
19756 bool BVNIsConstantSplat =
19758 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19759 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19770 if (SplatBits == (EltBits - 1)) {
19774 NewOpc = PPCISD::SHL;
19777 NewOpc = PPCISD::SRL;
19780 NewOpc = PPCISD::SRA;
19784 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19792 if (EltTy != MVT::i64 || SplatBits != 1)
19795 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19798SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19802 if (
N->getValueType(0).isVector())
19803 return combineVectorShift(
N, DCI);
19807 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19810 N->getValueType(0) != MVT::i64)
19825 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19831SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19835 if (
N->getValueType(0).isVector())
19836 return combineVectorShift(
N, DCI);
19841SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19845 if (
N->getValueType(0).isVector())
19846 return combineVectorShift(
N, DCI);
19857 if (!Subtarget.isPPC64())
19863 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19865 Op.getValueType() != MVT::i64)
19869 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19870 Cmp.getOperand(0).getValueType() != MVT::i64)
19874 int64_t NegConstant = 0 -
Constant->getSExtValue();
19883 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19884 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19887 if (LHSHasPattern && !RHSHasPattern)
19889 else if (!LHSHasPattern && !RHSHasPattern)
19893 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19896 SDValue Z = Cmp.getOperand(0);
19898 int64_t NegConstant = 0 -
Constant->getSExtValue();
19911 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19929 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19959 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19962 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19970 if (!GSDN || !ConstNode)
19998 EVT VT =
N->getValueType(0);
19999 if (!Subtarget.hasVSX())
20003 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20015 unsigned NumOfEles =
RHS.getNumOperands();
20016 for (
unsigned i = 0; i < NumOfEles; ++i) {
20018 if (!CN || CN->getSExtValue() != 1)
20033SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20055 DAGCombinerInfo &DCI)
const {
20057 if (Subtarget.useCRBits()) {
20059 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20060 return CRTruncValue;
20067 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20070 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20080 EltToExtract = EltToExtract ? 0 : 1;
20090 return DCI.DAG.getNode(
20092 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20097SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20098 SelectionDAG &DAG = DCI.DAG;
20101 if (!ConstOpOrElement)
20109 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20110 switch (this->Subtarget.getCPUDirective()) {
20133 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20137 EVT VT =
N->getValueType(0);
20142 APInt MulAmtAbs = MulAmt.
abs();
20144 if ((MulAmtAbs - 1).isPowerOf2()) {
20148 if (!IsProfitable(IsNeg,
true, VT))
20161 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20165 if (!IsProfitable(IsNeg,
false, VT))
20186 DAGCombinerInfo &DCI)
const {
20190 SDNodeFlags
Flags =
N->getFlags();
20191 EVT VT =
N->getValueType(0);
20192 SelectionDAG &DAG = DCI.DAG;
20193 unsigned Opc =
N->getOpcode();
20195 bool LegalOps = !DCI.isBeforeLegalizeOps();
20203 if (!
Flags.hasNoSignedZeros())
20219bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20221 if (!Subtarget.is64BitELFABI())
20231 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
20236 if (!Callee ||
Callee->isVarArg())
20249bool PPCTargetLowering::
20250isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20255 if (CI->getBitWidth() > 64)
20257 int64_t ConstVal = CI->getZExtValue();
20259 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20268PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20274 if ((Flags & FlagSet) == FlagSet)
20277 if ((Flags & FlagSet) == FlagSet)
20280 if ((Flags & FlagSet) == FlagSet)
20283 if ((Flags & FlagSet) == FlagSet)
20304 if ((FrameIndexAlign % 4) != 0)
20305 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20306 if ((FrameIndexAlign % 16) != 0)
20307 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20311 if ((FrameIndexAlign % 4) == 0)
20313 if ((FrameIndexAlign % 16) == 0)
20326 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20327 if ((Imm & 0x3) == 0)
20329 if ((Imm & 0xf) == 0)
20335 const APInt &ConstImm = CN->getAPIntValue();
20354 const APInt &ConstImm = CN->getAPIntValue();
20364 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20375 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20384unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20389 if (!Subtarget.hasP9Vector())
20394 if (Subtarget.hasPrefixInstrs())
20397 if (Subtarget.hasSPE())
20406 unsigned ParentOp = Parent->
getOpcode();
20410 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20411 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20423 if (LSB->isIndexed())
20429 assert(MN &&
"Parent should be a MemSDNode!");
20434 "Not expecting scalar integers larger than 16 bytes!");
20437 else if (
Size == 32)
20444 else if (
Size == 256) {
20445 assert(Subtarget.pairedVectorMemops() &&
20446 "256-bit vectors are only available when paired vector memops is "
20454 else if (MemVT == MVT::f128 || MemVT.
isVector())
20485 FlagSet &= ~PPC::MOF_NoExt;
20490 bool IsNonP1034BitConst =
20494 IsNonP1034BitConst)
20507 int16_t ForceXFormImm = 0;
20510 Disp =
N.getOperand(0);
20511 Base =
N.getOperand(1);
20522 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20523 Disp =
N.getOperand(0);
20524 Base =
N.getOperand(1);
20529 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20538 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20544 if (PartVT == MVT::f64 &&
20545 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20554SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20558 EVT RetVT =
Op.getValueType();
20565 EVT ArgVT =
N.getValueType();
20569 Entry.IsZExt = !Entry.IsSExt;
20570 Args.push_back(Entry);
20578 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20591SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20592 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20594 if (
Op.getValueType() == MVT::f32)
20595 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20597 if (
Op.getValueType() == MVT::f64)
20598 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20603bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20604 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20605 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20609bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20610 return Op.getNode()->getFlags().hasApproximateFuncs();
20613bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20617SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20618 const char *LibCallFloatName,
20619 const char *LibCallDoubleNameFinite,
20620 const char *LibCallFloatNameFinite,
20623 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20626 if (!isLowringToMASSFiniteSafe(
Op))
20627 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20630 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20631 LibCallDoubleNameFinite,
Op, DAG);
20635 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20636 "__xl_powf_finite",
Op, DAG);
20640 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20641 "__xl_sinf_finite",
Op, DAG);
20645 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20646 "__xl_cosf_finite",
Op, DAG);
20650 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20651 "__xl_logf_finite",
Op, DAG);
20655 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20656 "__xl_log10f_finite",
Op, DAG);
20660 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20661 "__xl_expf_finite",
Op, DAG);
20686 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20697 assert(Subtarget.isUsingPCRelativeCalls() &&
20698 "Must be using PC-Relative calls when a valid PC-Relative node is "
20728 Disp =
N.getOperand(1).getOperand(0);
20733 Base =
N.getOperand(0);
20741 EVT CNType = CN->getValueType(0);
20742 uint64_t CNImm = CN->getZExtValue();
20753 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20755 int32_t Addr = (int32_t)CNImm;
20760 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20776 unsigned Opcode =
N.getOpcode();
20784 Base =
N.getOperand(0);
20803 Base = FI ?
N :
N.getOperand(1);
20804 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20815 bool IsVarArg)
const {
20825 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20862 return Intrinsic::ppc_atomicrmw_xchg_i128;
20864 return Intrinsic::ppc_atomicrmw_add_i128;
20866 return Intrinsic::ppc_atomicrmw_sub_i128;
20868 return Intrinsic::ppc_atomicrmw_and_i128;
20870 return Intrinsic::ppc_atomicrmw_or_i128;
20872 return Intrinsic::ppc_atomicrmw_xor_i128;
20874 return Intrinsic::ppc_atomicrmw_nand_i128;
20882 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20886 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20888 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20889 Value *LoHi = Builder.CreateIntrinsic(
20891 {AlignedAddr, IncrLo, IncrHi});
20892 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20893 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20894 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20895 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20896 return Builder.CreateOr(
20897 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20904 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20910 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20912 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20913 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20915 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20918 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20920 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20921 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20922 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20923 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20924 return Builder.CreateOr(
20925 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20929 return Subtarget.useCRBits();
20934bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
20945 DAGCombinerInfo &DCI)
const {
20950 EVT ResVT =
N->getValueType(0);
20952 EVT SrcVT = Src.getValueType();
20957 if (ResVT != MVT::i16 && ResVT != MVT::i8)
20960 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
20973 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
20974 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
20975 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
20977 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
20985 SmallVector<int, 16> BitIndices(16, 128);
20989 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
20990 if (IsV8i8 && IsLE)
20991 BitIndices[Idx] += 64;
20994 std::reverse(BitIndices.begin(), BitIndices.end());
20996 for (
auto Idx : BitIndices)
21001 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
MachineInstr unsigned OpIdx
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static MachineBasicBlock * emitAtomicCmpSwapSoftware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit software-emulated atomic compare-and-swap for I8/I16 without hardware partword atomic support.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static void prepareOutOfLineGlueCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool 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 IsSelectCC(unsigned Opcode)
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue combineXorSelectCC(SDNode *N, SelectionDAG &DAG)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static 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 combineSELECT_CCBitFloor(SDNode *N, SelectionDAG &DAG)
Optimize the bitfloor(X) pattern for PowerPC.
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static MachineBasicBlock * emitSelect(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit SELECT instruction, using ISEL if available, otherwise use branch-based control flow.
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool canConvertSETCCToXori(SDNode *N)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static void createAtomicLoopBlocks(MachineFunction *F, MachineBasicBlock *BB, MachineBasicBlock *&loop1MBB, MachineBasicBlock *&loop2MBB, MachineBasicBlock *&exitMBB, MachineInstr &MI, MachineFunction::iterator It)
Helper function to create basic blocks for atomic compare-and-swap.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue combineZextSetccWithZero(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
static MachineBasicBlock * emitAtomicCmpSwapHardware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit hardware-supported atomic compare-and-swap for I32/I64 and I8/I16 with partword atomic support.
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static void signExtendOperandIfUnknown(MachineInstr &MI, MachineBasicBlock *BB, unsigned OpIdx, bool IsByte, const PPCInstrInfo *TII)
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
static 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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
LLVM_ABI StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
LLVM_ABI bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
Tracks which library functions to use for a particular subtarget.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
MCRegister getGlueCodeDescriptorRegister() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
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...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
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,...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(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.
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
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode, SDNodeFlags Flags={}) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual TargetLoweringObjectFile * getObjFileLowering() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
bool getFunctionSections() const
Return true if functions should be emitted into their own section, corresponding to -ffunction-sectio...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering)
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr RegState getDefRegState(bool B)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.