69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
149 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
153 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
154 "function to use initial-exec"));
159 "Number of shuffles lowered to a VPERM or XXPERM");
160STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
181 initializeAddrModeMap();
184 bool isPPC64 = Subtarget.isPPC64();
186 const MVT RegVT = Subtarget.getScalarIntVT();
194 if (!Subtarget.hasEFPU2())
211 if (!Subtarget.hasP10Vector()) {
240 if (Subtarget.isISA3_0()) {
273 if (!Subtarget.hasSPE()) {
280 if (Subtarget.useCRBits()) {
283 if (isPPC64 || Subtarget.hasFPCVT()) {
349 if (Subtarget.isISA3_0()) {
384 if (!Subtarget.hasSPE()) {
389 if (Subtarget.hasVSX()) {
394 if (Subtarget.hasFSQRT()) {
399 if (Subtarget.hasFPRND()) {
440 if (Subtarget.hasSPE()) {
450 if (Subtarget.hasSPE())
454 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
457 if (!Subtarget.hasFSQRT() &&
458 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
461 if (Subtarget.hasFCPSGN()) {
469 if (Subtarget.hasFPRND()) {
483 if (Subtarget.isISA3_1()) {
489 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
493 if (Subtarget.isISA3_0()) {
513 if (!Subtarget.useCRBits()) {
526 if (!Subtarget.useCRBits())
529 if (Subtarget.hasFPU()) {
540 if (!Subtarget.useCRBits())
545 if (Subtarget.hasSPE()) {
569 if (Subtarget.hasDirectMove() && isPPC64) {
629 if (Subtarget.is64BitELFABI()) {
640 }
else if (Subtarget.is32BitELFABI()) {
648 if (Subtarget.is32BitELFABI())
664 if (Subtarget.isISA3_0() && isPPC64) {
692 if (Subtarget.hasSPE()) {
714 if (Subtarget.has64BitSupport()) {
729 if (Subtarget.hasLFIWAX() || isPPC64) {
735 if (Subtarget.hasSPE()) {
745 if (Subtarget.hasFPCVT()) {
746 if (Subtarget.has64BitSupport()) {
767 if (Subtarget.use64BitRegs()) {
785 if (Subtarget.has64BitSupport()) {
792 if (Subtarget.hasVSX()) {
805 if (Subtarget.hasAltivec()) {
806 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
821 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
834 if (Subtarget.hasVSX()) {
843 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
853 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
927 if (!Subtarget.hasP8Vector()) {
969 if (Subtarget.hasAltivec())
970 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
973 if (Subtarget.hasP8Altivec())
984 if (Subtarget.hasVSX()) {
990 if (Subtarget.hasP8Altivec())
995 if (Subtarget.isISA3_1()) {
1041 if (Subtarget.hasVSX()) {
1044 if (Subtarget.hasP8Vector()) {
1048 if (Subtarget.hasDirectMove() && isPPC64) {
1097 if (Subtarget.hasP8Vector())
1106 if (Subtarget.hasP8Altivec()) {
1133 if (Subtarget.isISA3_1())
1236 if (Subtarget.hasP8Altivec()) {
1241 if (Subtarget.hasP9Vector()) {
1246 if (Subtarget.useCRBits()) {
1306 }
else if (Subtarget.hasVSX()) {
1331 for (
MVT VT : {MVT::f32, MVT::f64}) {
1350 if (Subtarget.hasP9Altivec()) {
1351 if (Subtarget.isISA3_1()) {
1374 if (Subtarget.hasP10Vector()) {
1379 if (Subtarget.pairedVectorMemops()) {
1384 if (Subtarget.hasMMA()) {
1385 if (Subtarget.isISAFuture()) {
1401 if (Subtarget.has64BitSupport())
1404 if (Subtarget.isISA3_1())
1422 if (Subtarget.hasAltivec()) {
1439 if (Subtarget.hasFPCVT())
1442 if (Subtarget.useCRBits())
1451 if (Subtarget.useCRBits()) {
1457 if (Subtarget.useCRBits()) {
1473 auto CPUDirective = Subtarget.getCPUDirective();
1474 switch (CPUDirective) {
1497 if (Subtarget.enableMachineScheduler())
1571void PPCTargetLowering::initializeAddrModeMap() {
1622 if (MaxAlign == MaxMaxAlign)
1625 if (MaxMaxAlign >= 32 &&
1626 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1627 MaxAlign =
Align(32);
1628 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1630 MaxAlign =
Align(16);
1634 if (EltAlign > MaxAlign)
1635 MaxAlign = EltAlign;
1637 for (
auto *EltTy : STy->elements()) {
1640 if (EltAlign > MaxAlign)
1641 MaxAlign = EltAlign;
1642 if (MaxAlign == MaxMaxAlign)
1655 if (Subtarget.hasAltivec())
1661 return Subtarget.useSoftFloat();
1665 return Subtarget.hasSPE();
1673 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1674 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1678 if (VTy->getScalarType()->isIntegerTy()) {
1680 if (ElemSizeInBits == 32) {
1681 Index = Subtarget.isLittleEndian() ? 2 : 1;
1684 if (ElemSizeInBits == 64) {
1685 Index = Subtarget.isLittleEndian() ? 1 : 0;
1696 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1713 return CFP->getValueAPF().isZero();
1718 return CFP->getValueAPF().isZero();
1726 return Op < 0 ||
Op == Val;
1738 if (ShuffleKind == 0) {
1741 for (
unsigned i = 0; i != 16; ++i)
1744 }
else if (ShuffleKind == 2) {
1747 for (
unsigned i = 0; i != 16; ++i)
1750 }
else if (ShuffleKind == 1) {
1751 unsigned j = IsLE ? 0 : 1;
1752 for (
unsigned i = 0; i != 8; ++i)
1769 if (ShuffleKind == 0) {
1772 for (
unsigned i = 0; i != 16; i += 2)
1776 }
else if (ShuffleKind == 2) {
1779 for (
unsigned i = 0; i != 16; i += 2)
1783 }
else if (ShuffleKind == 1) {
1784 unsigned j = IsLE ? 0 : 2;
1785 for (
unsigned i = 0; i != 8; i += 2)
1806 if (!Subtarget.hasP8Vector())
1810 if (ShuffleKind == 0) {
1813 for (
unsigned i = 0; i != 16; i += 4)
1819 }
else if (ShuffleKind == 2) {
1822 for (
unsigned i = 0; i != 16; i += 4)
1828 }
else if (ShuffleKind == 1) {
1829 unsigned j = IsLE ? 0 : 4;
1830 for (
unsigned i = 0; i != 8; i += 4)
1847 unsigned LHSStart,
unsigned RHSStart) {
1848 if (
N->getValueType(0) != MVT::v16i8)
1850 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1851 "Unsupported merge size!");
1853 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1854 for (
unsigned j = 0; j != UnitSize; ++j) {
1856 LHSStart+j+i*UnitSize) ||
1858 RHSStart+j+i*UnitSize))
1873 if (ShuffleKind == 1)
1875 else if (ShuffleKind == 2)
1880 if (ShuffleKind == 1)
1882 else if (ShuffleKind == 0)
1898 if (ShuffleKind == 1)
1900 else if (ShuffleKind == 2)
1905 if (ShuffleKind == 1)
1907 else if (ShuffleKind == 0)
1957 unsigned RHSStartValue) {
1958 if (
N->getValueType(0) != MVT::v16i8)
1961 for (
unsigned i = 0; i < 2; ++i)
1962 for (
unsigned j = 0; j < 4; ++j)
1964 i*RHSStartValue+j+IndexOffset) ||
1966 i*RHSStartValue+j+IndexOffset+8))
1988 unsigned indexOffset = CheckEven ? 4 : 0;
1989 if (ShuffleKind == 1)
1991 else if (ShuffleKind == 2)
1997 unsigned indexOffset = CheckEven ? 0 : 4;
1998 if (ShuffleKind == 1)
2000 else if (ShuffleKind == 0)
2016 if (
N->getValueType(0) != MVT::v16i8)
2023 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2026 if (i == 16)
return -1;
2031 if (ShiftAmt < i)
return -1;
2036 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2038 for (++i; i != 16; ++i)
2041 }
else if (ShuffleKind == 1) {
2043 for (++i; i != 16; ++i)
2050 ShiftAmt = 16 - ShiftAmt;
2059 EVT VT =
N->getValueType(0);
2060 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2061 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2064 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2068 if (
N->getMaskElt(0) % EltSize != 0)
2073 unsigned ElementBase =
N->getMaskElt(0);
2076 if (ElementBase >= 16)
2081 for (
unsigned i = 1; i != EltSize; ++i)
2082 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2085 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2087 if (
N->getMaskElt(i) < 0) {
2088 for (
unsigned j = 1; j != EltSize; ++j)
2089 if (
N->getMaskElt(i + j) >= 0)
2092 for (
unsigned j = 0; j != EltSize; ++j)
2093 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2110 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2111 "Unexpected element width.");
2112 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2114 unsigned NumOfElem = 16 / Width;
2115 unsigned MaskVal[16];
2116 for (
unsigned i = 0; i < NumOfElem; ++i) {
2117 MaskVal[0] =
N->getMaskElt(i * Width);
2118 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2120 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2124 for (
unsigned int j = 1; j < Width; ++j) {
2125 MaskVal[j] =
N->getMaskElt(i * Width + j);
2126 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2136 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2141 unsigned M0 =
N->getMaskElt(0) / 4;
2142 unsigned M1 =
N->getMaskElt(4) / 4;
2143 unsigned M2 =
N->getMaskElt(8) / 4;
2144 unsigned M3 =
N->getMaskElt(12) / 4;
2145 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2146 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2151 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2152 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2153 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2154 InsertAtByte = IsLE ? 12 : 0;
2159 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2160 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2161 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2162 InsertAtByte = IsLE ? 8 : 4;
2167 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2168 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2169 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2170 InsertAtByte = IsLE ? 4 : 8;
2175 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2176 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2177 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2178 InsertAtByte = IsLE ? 0 : 12;
2185 if (
N->getOperand(1).isUndef()) {
2188 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2189 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2190 InsertAtByte = IsLE ? 12 : 0;
2193 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2194 InsertAtByte = IsLE ? 8 : 4;
2197 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2198 InsertAtByte = IsLE ? 4 : 8;
2201 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2202 InsertAtByte = IsLE ? 0 : 12;
2211 bool &Swap,
bool IsLE) {
2212 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2218 unsigned M0 =
N->getMaskElt(0) / 4;
2219 unsigned M1 =
N->getMaskElt(4) / 4;
2220 unsigned M2 =
N->getMaskElt(8) / 4;
2221 unsigned M3 =
N->getMaskElt(12) / 4;
2225 if (
N->getOperand(1).isUndef()) {
2226 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2227 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2230 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2236 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2240 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2245 ShiftElts = (8 -
M0) % 8;
2246 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2251 ShiftElts = (4 -
M0) % 4;
2256 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2261 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2273 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2278 for (
int i = 0; i < 16; i += Width)
2279 if (
N->getMaskElt(i) != i + Width - 1)
2310 bool &Swap,
bool IsLE) {
2311 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2317 unsigned M0 =
N->getMaskElt(0) / 8;
2318 unsigned M1 =
N->getMaskElt(8) / 8;
2319 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2323 if (
N->getOperand(1).isUndef()) {
2324 if ((
M0 |
M1) < 2) {
2325 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2333 if (
M0 > 1 &&
M1 < 2) {
2343 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2348 }
else if (
M0 > 1 &&
M1 < 2) {
2356 DM = (
M0 << 1) + (
M1 & 1);
2371 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2376 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2392 unsigned EltSize = 16/
N->getNumOperands();
2393 if (EltSize < ByteSize) {
2394 unsigned Multiple = ByteSize/EltSize;
2396 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2399 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2400 if (
N->getOperand(i).isUndef())
continue;
2404 if (!UniquedVals[i&(Multiple-1)].
getNode())
2405 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2406 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2416 bool LeadingZero =
true;
2417 bool LeadingOnes =
true;
2418 for (
unsigned i = 0; i != Multiple-1; ++i) {
2419 if (!UniquedVals[i].
getNode())
continue;
2426 if (!UniquedVals[Multiple-1].
getNode())
2433 if (!UniquedVals[Multiple-1].
getNode())
2444 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2445 if (
N->getOperand(i).isUndef())
continue;
2447 OpVal =
N->getOperand(i);
2448 else if (OpVal !=
N->getOperand(i))
2454 unsigned ValSizeInBytes = EltSize;
2457 Value = CN->getZExtValue();
2459 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2466 if (ValSizeInBytes < ByteSize)
return SDValue();
2477 if (MaskVal == 0)
return SDValue();
2497 Imm = (int16_t)
N->getAsZExtVal();
2498 if (
N->getValueType(0) == MVT::i32)
2499 return Imm == (int32_t)
N->getAsZExtVal();
2501 return Imm == (int64_t)
N->getAsZExtVal();
2519 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2527 for (
SDNode *U :
N->users()) {
2529 if (Memop->getMemoryVT() == MVT::f64) {
2530 Base =
N.getOperand(0);
2531 Index =
N.getOperand(1);
2574 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2576 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2579 Base =
N.getOperand(0);
2580 Index =
N.getOperand(1);
2582 }
else if (
N.getOpcode() ==
ISD::OR) {
2584 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2596 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2597 Base =
N.getOperand(0);
2598 Index =
N.getOperand(1);
2668 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2674 Base =
N.getOperand(0);
2677 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2679 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2680 "Cannot handle constant offsets yet!");
2681 Disp =
N.getOperand(1).getOperand(0);
2686 Base =
N.getOperand(0);
2689 }
else if (
N.getOpcode() ==
ISD::OR) {
2692 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2706 Base =
N.getOperand(0);
2719 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2722 CN->getValueType(0));
2727 if ((CN->getValueType(0) == MVT::i32 ||
2728 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2729 (!EncodingAlignment ||
2730 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2731 int Addr = (int)CN->getZExtValue();
2738 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2759 if (
N.getValueType() != MVT::i64)
2772 Base =
N.getOperand(0);
2788 Base =
N.getOperand(0);
2821 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2822 Base =
N.getOperand(0);
2823 Index =
N.getOperand(1);
2845 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2866 EVT MemVT = LD->getMemoryVT();
2873 if (!ST.hasP8Vector())
2878 if (!ST.hasP9Vector())
2890 if (
Use.getResNo() == 0 &&
2892 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2912 Ptr = LD->getBasePtr();
2913 VT = LD->getMemoryVT();
2914 Alignment = LD->getAlign();
2916 Ptr = ST->getBasePtr();
2917 VT = ST->getMemoryVT();
2918 Alignment = ST->getAlign();
2957 if (VT != MVT::i64) {
2962 if (Alignment <
Align(4))
2972 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
2989 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3031 EVT VT = Subtarget.getScalarIntVT();
3033 : Subtarget.isAIXABI()
3038 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3045 EVT PtrVT =
Op.getValueType();
3051 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3052 if (Subtarget.isUsingPCRelativeCalls()) {
3057 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3061 return getTOCEntry(DAG, SDLoc(CP), GA);
3064 unsigned MOHiFlag, MOLoFlag;
3068 if (IsPIC && Subtarget.isSVR4ABI()) {
3071 return getTOCEntry(DAG, SDLoc(CP), GA);
3094 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3101 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3118 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3131 EVT PtrVT =
Op.getValueType();
3149 return getTOCEntry(DAG,
SDLoc(JT), GA);
3152 unsigned MOHiFlag, MOLoFlag;
3156 if (IsPIC && Subtarget.isSVR4ABI()) {
3159 return getTOCEntry(DAG, SDLoc(GA), GA);
3169 EVT PtrVT =
Op.getValueType();
3174 if (Subtarget.isUsingPCRelativeCalls()) {
3185 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3188 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3197 unsigned MOHiFlag, MOLoFlag;
3207 if (Subtarget.isAIXABI())
3208 return LowerGlobalTLSAddressAIX(
Op, DAG);
3210 return LowerGlobalTLSAddressLinux(
Op, DAG);
3232 if (
I.getOpcode() == Instruction::Call)
3234 if (
Function *CF = CI->getCalledFunction())
3235 if (CF->isDeclaration() &&
3236 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3244 unsigned TLSGVCnt = TLSGV.
size();
3254 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3267 const GlobalValue *GV = GA->
getGlobal();
3269 bool Is64Bit = Subtarget.isPPC64();
3273 if (Subtarget.hasAIXShLibTLSModelOpt())
3283 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3284 bool HasAIXSmallTLSGlobalAttr =
false;
3287 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3291 if (GVar->hasAttribute(
"aix-small-tls"))
3292 HasAIXSmallTLSGlobalAttr =
true;
3311 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3312 IsTLSLocalExecModel) {
3317 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3327 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3332 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3334 "currently only supported on AIX (64-bit mode).");
3336 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3340 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3344 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3346 "currently only supported on AIX (64-bit mode).");
3354 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3357 GlobalVariable *TLSGV =
3361 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3364 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3366 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3375 if (HasAIXSmallLocalDynamicTLS) {
3380 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3384 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3397 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3398 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3399 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3414 const GlobalValue *GV = GA->
getGlobal();
3416 bool is64bit = Subtarget.isPPC64();
3424 if (Subtarget.isUsingPCRelativeCalls()) {
3429 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3430 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3441 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3445 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3452 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3454 MachinePointerInfo());
3461 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3463 if (!TM.isPositionIndependent())
3464 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3470 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3472 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3476 if (Subtarget.isUsingPCRelativeCalls()) {
3479 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3487 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3495 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3500 if (Subtarget.isUsingPCRelativeCalls()) {
3504 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3505 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3513 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3522 PtrVT, GOTPtr, TGA, TGA);
3524 PtrVT, TLSAddr, TGA);
3525 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3533 EVT PtrVT =
Op.getValueType();
3536 const GlobalValue *GV = GSDN->
getGlobal();
3540 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3541 if (Subtarget.isUsingPCRelativeCalls()) {
3548 MachinePointerInfo());
3553 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3558 return getTOCEntry(DAG,
DL, GA);
3561 unsigned MOHiFlag, MOLoFlag;
3565 if (IsPIC && Subtarget.isSVR4ABI()) {
3569 return getTOCEntry(DAG,
DL, GA);
3581 bool IsStrict =
Op->isStrictFPOpcode();
3587 EVT LHSVT =
LHS.getValueType();
3591 if (LHSVT == MVT::f128) {
3592 assert(!Subtarget.hasP9Vector() &&
3593 "SETCC for f128 is already legal under Power9!");
3604 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3606 if (
Op.getValueType() == MVT::v2i64) {
3609 if (
LHS.getValueType() == MVT::v2i64) {
3615 dl, MVT::v4i32, DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
LHS),
3616 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
RHS), CC);
3617 int ShuffV[] = {1, 0, 3, 2};
3622 dl, MVT::v4i32, Shuff, SetCC32));
3639 if (
C->isAllOnes() ||
C->isZero())
3649 EVT VT =
Op.getValueType();
3657 SDNode *
Node =
Op.getNode();
3658 EVT VT =
Node->getValueType(0);
3665 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3669 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3672 if (VT == MVT::i64) {
3691 FprPtr, MachinePointerInfo(SV), MVT::i8);
3702 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3703 InChain = OverflowArea.
getValue(1);
3706 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3736 MachinePointerInfo(SV), MVT::i8);
3749 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3750 MachinePointerInfo(), MVT::i32);
3752 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3756 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3762 false,
true,
nullptr, std::nullopt,
3763 MachinePointerInfo(), MachinePointerInfo());
3768 return Op.getOperand(0);
3773 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3775 assert((
Op.getOpcode() == ISD::INLINEASM ||
3776 Op.getOpcode() == ISD::INLINEASM_BR) &&
3777 "Expecting Inline ASM node.");
3787 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3792 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3793 unsigned NumVals =
Flags.getNumOperandRegisters();
3796 switch (
Flags.getKind()) {
3807 for (; NumVals; --NumVals, ++i) {
3809 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3832 if (Subtarget.isAIXABI()) {
3836 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3837 MaybeAlign PointerAlign(PointerSize);
3838 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3841 : MachineMemOperand::MONone;
3848 const Value *TrampolineAddr =
3858 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3859 PointerAlign, MMOFlags);
3861 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3862 MachinePointerInfo(TrampolineAddr, 0));
3866 SDValue TOCFromDescriptorPtr =
3868 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3869 MachinePointerInfo(Func, TOCPointerOffset),
3870 PointerAlign, MMOFlags);
3871 SDValue TrampolineTOCPointer =
3875 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3876 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3882 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3883 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3890 bool isPPC64 = (PtrVT == MVT::i64);
3894 Args.emplace_back(Trmp, IntPtrTy);
3897 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3899 Args.emplace_back(FPtr, IntPtrTy);
3900 Args.emplace_back(Nest, IntPtrTy);
3903 TargetLowering::CallLoweringInfo CLI(DAG);
3904 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3908 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3909 return CallResult.second;
3914 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3919 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3924 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3925 MachinePointerInfo(SV));
3959 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3962 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3965 uint64_t FPROffset = 1;
3973 MachinePointerInfo(SV), MVT::i8);
3974 uint64_t nextOffset = FPROffset;
3981 MachinePointerInfo(SV, nextOffset), MVT::i8);
3982 nextOffset += StackOffset;
3983 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3986 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3987 MachinePointerInfo(SV, nextOffset));
3988 nextOffset += FrameOffset;
3989 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
3992 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
3993 MachinePointerInfo(SV, nextOffset));
3998static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
3999 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4000 PPC::F11, PPC::F12, PPC::F13};
4005 unsigned PtrByteSize) {
4007 if (Flags.isByVal())
4008 ArgSize = Flags.getByValSize();
4012 if (!Flags.isInConsecutiveRegs())
4013 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4022 unsigned PtrByteSize) {
4023 Align Alignment(PtrByteSize);
4026 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4027 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4028 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4029 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4030 Alignment =
Align(16);
4033 if (Flags.isByVal()) {
4034 auto BVAlign = Flags.getNonZeroByValAlign();
4035 if (BVAlign > PtrByteSize) {
4036 if (BVAlign.value() % PtrByteSize != 0)
4038 "ByVal alignment is not a multiple of the pointer size");
4040 Alignment = BVAlign;
4045 if (Flags.isInConsecutiveRegs()) {
4049 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4063 unsigned PtrByteSize,
unsigned LinkageSize,
4064 unsigned ParamAreaSize,
unsigned &ArgOffset,
4065 unsigned &AvailableFPRs,
4066 unsigned &AvailableVRs) {
4067 bool UseMemory =
false;
4072 ArgOffset =
alignTo(ArgOffset, Alignment);
4075 if (ArgOffset >= LinkageSize + ParamAreaSize)
4080 if (Flags.isInConsecutiveRegsLast())
4081 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4084 if (ArgOffset > LinkageSize + ParamAreaSize)
4089 if (!Flags.isByVal()) {
4090 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4091 if (AvailableFPRs > 0) {
4095 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4096 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4097 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4098 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4099 if (AvailableVRs > 0) {
4111 unsigned NumBytes) {
4115SDValue PPCTargetLowering::LowerFormalArguments(
4119 if (Subtarget.isAIXABI())
4120 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4122 if (Subtarget.is64BitELFABI())
4123 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4125 assert(Subtarget.is32BitELFABI());
4126 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4130SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4166 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4172 const Align PtrAlign(4);
4180 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4181 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4184 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4185 CCValAssign &VA = ArgLocs[i];
4189 const TargetRegisterClass *RC;
4197 RC = &PPC::GPRCRegClass;
4200 if (Subtarget.hasP8Vector())
4201 RC = &PPC::VSSRCRegClass;
4202 else if (Subtarget.hasSPE())
4203 RC = &PPC::GPRCRegClass;
4205 RC = &PPC::F4RCRegClass;
4208 if (Subtarget.hasVSX())
4209 RC = &PPC::VSFRCRegClass;
4210 else if (Subtarget.hasSPE())
4212 RC = &PPC::GPRCRegClass;
4214 RC = &PPC::F8RCRegClass;
4219 RC = &PPC::VRRCRegClass;
4222 RC = &PPC::VRRCRegClass;
4226 RC = &PPC::VRRCRegClass;
4233 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4234 assert(i + 1 < e &&
"No second half of double precision argument");
4239 if (!Subtarget.isLittleEndian())
4241 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4246 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4247 if (ValVT == MVT::i1)
4262 ArgOffset += ArgSize - ObjSize;
4280 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4285 unsigned MinReservedArea = CCByValInfo.getStackSize();
4286 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4302 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4303 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4305 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4308 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4311 unsigned NumFPArgRegs = std::size(FPArgRegs);
4320 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4321 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4324 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4337 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4352 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4356 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4369 if (!MemOps.
empty())
4380 const SDLoc &dl)
const {
4384 else if (
Flags.isZExt())
4391SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4397 bool isELFv2ABI = Subtarget.isELFv2ABI();
4398 bool isLittleEndian = Subtarget.isLittleEndian();
4401 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4404 "fastcc not supported on varargs functions");
4410 unsigned PtrByteSize = 8;
4411 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4414 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4415 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4418 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4419 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4422 const unsigned Num_GPR_Regs = std::size(GPR);
4424 const unsigned Num_VR_Regs = std::size(VR);
4432 bool HasParameterArea = !isELFv2ABI || isVarArg;
4433 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4434 unsigned NumBytes = LinkageSize;
4435 unsigned AvailableFPRs = Num_FPR_Regs;
4436 unsigned AvailableVRs = Num_VR_Regs;
4437 for (
const ISD::InputArg &In : Ins) {
4438 if (
In.Flags.isNest())
4442 LinkageSize, ParamAreaSize, NumBytes,
4443 AvailableFPRs, AvailableVRs))
4444 HasParameterArea =
true;
4451 unsigned ArgOffset = LinkageSize;
4452 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4455 unsigned CurArgIdx = 0;
4456 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4458 bool needsLoad =
false;
4459 EVT ObjectVT = Ins[ArgNo].VT;
4460 EVT OrigVT = Ins[ArgNo].ArgVT;
4462 unsigned ArgSize = ObjSize;
4463 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4464 if (Ins[ArgNo].isOrigArg()) {
4465 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4466 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4471 unsigned CurArgOffset;
4473 auto ComputeArgOffset = [&]() {
4477 ArgOffset =
alignTo(ArgOffset, Alignment);
4478 CurArgOffset = ArgOffset;
4485 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4486 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4491 if (
Flags.isByVal()) {
4492 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4498 ObjSize =
Flags.getByValSize();
4499 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4521 if (HasParameterArea ||
4522 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4529 if (ObjSize < PtrByteSize) {
4533 if (!isLittleEndian) {
4539 if (GPR_idx != Num_GPR_Regs) {
4546 MachinePointerInfo(&*FuncArg), ObjType);
4551 ArgOffset += PtrByteSize;
4560 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4561 if (GPR_idx == Num_GPR_Regs)
4572 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4576 MachinePointerInfo(&*FuncArg, j), ObjType);
4580 ArgOffset += ArgSize;
4589 if (
Flags.isNest()) {
4594 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4595 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4603 if (GPR_idx != Num_GPR_Regs) {
4608 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4611 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4617 ArgSize = PtrByteSize;
4628 if (FPR_idx != Num_FPR_Regs) {
4631 if (ObjectVT == MVT::f32)
4633 Subtarget.hasP8Vector()
4634 ? &PPC::VSSRCRegClass
4635 : &PPC::F4RCRegClass);
4638 ? &PPC::VSFRCRegClass
4639 : &PPC::F8RCRegClass);
4654 if (ObjectVT == MVT::f32) {
4655 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4661 ArgVal = DAG.
getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
4673 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4674 ArgOffset += ArgSize;
4675 if (
Flags.isInConsecutiveRegsLast())
4676 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4690 if (VR_idx != Num_VR_Regs) {
4707 if (ObjSize < ArgSize && !isLittleEndian)
4708 CurArgOffset += ArgSize - ObjSize;
4711 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4718 unsigned MinReservedArea;
4719 if (HasParameterArea)
4720 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4722 MinReservedArea = LinkageSize;
4739 int Depth = ArgOffset;
4748 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4749 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4761 if (!MemOps.
empty())
4770 unsigned ParamSize) {
4772 if (!isTailCall)
return 0;
4776 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4778 if (SPDiff < FI->getTailCallSPDelta())
4794 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4853 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4856 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4868 const unsigned PtrByteSize = 8;
4872 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4873 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4876 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4877 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4880 const unsigned NumGPRs = std::size(GPR);
4881 const unsigned NumFPRs = 13;
4882 const unsigned NumVRs = std::size(VR);
4883 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4885 unsigned NumBytes = LinkageSize;
4886 unsigned AvailableFPRs = NumFPRs;
4887 unsigned AvailableVRs = NumVRs;
4890 if (Param.Flags.isNest())
continue;
4893 LinkageSize, ParamAreaSize, NumBytes,
4894 AvailableFPRs, AvailableVRs))
4905 auto CalleeArgEnd = CB.
arg_end();
4908 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4909 const Value* CalleeArg = *CalleeArgIter;
4910 const Value* CallerArg = &(*CallerArgIter);
4911 if (CalleeArg == CallerArg)
4937 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4947bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4952 bool isCalleeExternalSymbol)
const {
4955 if (
DisableSCO && !TailCallOpt)
return false;
4958 if (isVarArg)
return false;
4965 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5001 if (!Subtarget.isUsingPCRelativeCalls() &&
5006 if (!Subtarget.isUsingPCRelativeCalls() &&
5034bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5047 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5068 if (!
C)
return nullptr;
5070 int Addr =
C->getZExtValue();
5071 if ((Addr & 3) != 0 ||
5077 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5084struct TailCallArgumentInfo {
5089 TailCallArgumentInfo() =
default;
5099 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5100 SDValue Arg = TailCallArgs[i].Arg;
5101 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5102 int FI = TailCallArgs[i].FrameIdx;
5105 Chain, dl, Arg, FIN,
5114 int SPDiff,
const SDLoc &dl) {
5120 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5121 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5123 NewRetAddrLoc,
true);
5126 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5136 int SPDiff,
unsigned ArgOffset,
5138 int Offset = ArgOffset + SPDiff;
5141 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5143 TailCallArgumentInfo
Info;
5145 Info.FrameIdxOp = FIN;
5153SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5158 LROpOut = getReturnAddrFrameIndex(DAG);
5159 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5160 MachinePointerInfo());
5177 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5185 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5209 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5219 if (!MemOpChains2.
empty())
5243SDValue PPCTargetLowering::LowerCallResult(
5251 CCRetInfo.AnalyzeCallResult(
5257 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5258 CCValAssign &VA = RVLocs[i];
5263 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5273 if (!Subtarget.isLittleEndian())
5275 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5341 bool IsStrictFPCall =
false) {
5343 return PPCISD::TC_RETURN;
5345 unsigned RetOpc = 0;
5360 RetOpc = PPCISD::CALL_NOTOC;
5375 RetOpc = PPCISD::CALL;
5376 if (IsStrictFPCall) {
5380 case PPCISD::BCTRL_LOAD_TOC:
5381 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5384 RetOpc = PPCISD::BCTRL_RM;
5386 case PPCISD::CALL_NOTOC:
5387 RetOpc = PPCISD::CALL_NOTOC_RM;
5390 RetOpc = PPCISD::CALL_RM;
5392 case PPCISD::CALL_NOP:
5393 RetOpc = PPCISD::CALL_NOP_RM;
5407 auto isLocalCallee = [&]() {
5423 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5440 return getAIXFuncEntryPointSymbolSDNode(GV);
5447 const char *SymName = S->getSymbol();
5454 return getAIXFuncEntryPointSymbolSDNode(
F);
5460 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5468 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5475 assert(Callee.getNode() &&
"What no callee?");
5481 "Expected a CALLSEQ_STARTSDNode.");
5498 SDValue MTCTROps[] = {Chain, Callee, Glue};
5499 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5500 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5540 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5559 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5560 Alignment, MMOFlags);
5567 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5574 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5586 "Nest parameter is not supported on AIX.");
5602 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5605 const bool IsPPC64 = Subtarget.isPPC64();
5610 Ops.push_back(Chain);
5614 Ops.push_back(Callee);
5634 Ops.push_back(AddTOC);
5645 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5654 for (
const auto &[
Reg,
N] : RegsToPass)
5672 assert(Mask &&
"Missing call preserved mask for calling convention");
5677 Ops.push_back(Glue);
5680SDValue PPCTargetLowering::FinishCall(
5687 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5688 Subtarget.isAIXABI())
5695 if (!CFlags.IsIndirect)
5697 else if (Subtarget.usesFunctionDescriptors())
5699 dl, CFlags.HasNest, Subtarget);
5709 if (CFlags.IsTailCall) {
5717 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5718 "Expecting a global address, external symbol, absolute value, "
5719 "register or an indirect tail call when PC Relative calls are "
5722 assert(CallOpc == PPCISD::TC_RETURN &&
5723 "Unexpected call opcode for a tail call.");
5730 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5731 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5743 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5746 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5766 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5767 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5771bool PPCTargetLowering::isEligibleForTCO(
5776 bool isCalleeExternalSymbol)
const {
5780 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5781 return IsEligibleForTailCallOptimization_64SVR4(
5782 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5783 isCalleeExternalSymbol);
5785 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5813 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5828 "Callee should be an llvm::Function object.");
5831 <<
"\nTCO callee: ");
5838 "site marked musttail");
5845 Callee = LowerGlobalAddress(Callee, DAG);
5848 CallConv, isTailCall, isVarArg, isPatchPoint,
5851 Subtarget.is64BitELFABI() &&
5855 if (Subtarget.isAIXABI())
5856 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5859 assert(Subtarget.isSVR4ABI());
5860 if (Subtarget.isPPC64())
5861 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5863 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5867SDValue PPCTargetLowering::LowerCall_32SVR4(
5878 const bool IsVarArg = CFlags.IsVarArg;
5879 const bool IsTailCall = CFlags.IsTailCall;
5885 const Align PtrAlign(4);
5896 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5904 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5907 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5914 unsigned NumArgs = Outs.
size();
5916 for (
unsigned i = 0; i != NumArgs; ++i) {
5917 MVT ArgVT = Outs[i].VT;
5918 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5923 Outs[i].OrigTy, CCInfo);
5926 ArgFlags, Outs[i].OrigTy, CCInfo);
5931 errs() <<
"Call operand #" << i <<
" has unhandled type "
5944 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
5947 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
5954 unsigned NumBytes = CCByValInfo.getStackSize();
5968 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
5979 bool seenFloatArg =
false;
5984 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
5986 ++i, ++RealArgIdx) {
5987 CCValAssign &VA = ArgLocs[i];
5988 SDValue Arg = OutVals[RealArgIdx];
5989 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
5991 if (
Flags.isByVal()) {
5996 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
5997 CCValAssign &ByValVA = ByValArgLocs[
j++];
6019 Chain = CallSeqStart = NewCallSeqStart;
6038 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6039 bool IsLE = Subtarget.isLittleEndian();
6040 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6043 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6045 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6060 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6069 if (!MemOpChains.
empty())
6075 for (
const auto &[
Reg,
N] : RegsToPass) {
6083 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6086 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6096 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6097 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6102SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6114 return NewCallSeqStart;
6117SDValue PPCTargetLowering::LowerCall_64SVR4(
6124 bool isELFv2ABI = Subtarget.isELFv2ABI();
6125 bool isLittleEndian = Subtarget.isLittleEndian();
6127 bool IsSibCall =
false;
6131 unsigned PtrByteSize = 8;
6144 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6146 assert(!(IsFastCall && CFlags.IsVarArg) &&
6147 "fastcc not supported on varargs functions");
6153 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6154 unsigned NumBytes = LinkageSize;
6155 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6158 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6159 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6162 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6163 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6166 const unsigned NumGPRs = std::size(GPR);
6168 const unsigned NumVRs = std::size(VR);
6174 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6175 if (!HasParameterArea) {
6176 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6177 unsigned AvailableFPRs = NumFPRs;
6178 unsigned AvailableVRs = NumVRs;
6179 unsigned NumBytesTmp = NumBytes;
6180 for (
unsigned i = 0; i !=
NumOps; ++i) {
6181 if (Outs[i].
Flags.isNest())
continue;
6183 PtrByteSize, LinkageSize, ParamAreaSize,
6184 NumBytesTmp, AvailableFPRs, AvailableVRs))
6185 HasParameterArea =
true;
6191 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6196 HasParameterArea =
false;
6199 for (
unsigned i = 0; i !=
NumOps; ++i) {
6200 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6201 EVT ArgVT = Outs[i].VT;
6202 EVT OrigVT = Outs[i].ArgVT;
6208 if (
Flags.isByVal()) {
6209 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6210 if (NumGPRsUsed > NumGPRs)
6211 HasParameterArea =
true;
6218 if (++NumGPRsUsed <= NumGPRs)
6228 if (++NumVRsUsed <= NumVRs)
6232 if (++NumVRsUsed <= NumVRs)
6237 if (++NumFPRsUsed <= NumFPRs)
6241 HasParameterArea =
true;
6248 NumBytes =
alignTo(NumBytes, Alignement);
6251 if (
Flags.isInConsecutiveRegsLast())
6252 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6255 unsigned NumBytesActuallyUsed = NumBytes;
6265 if (HasParameterArea)
6266 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6268 NumBytes = LinkageSize;
6283 if (CFlags.IsTailCall)
6295 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6306 unsigned ArgOffset = LinkageSize;
6312 for (
unsigned i = 0; i !=
NumOps; ++i) {
6314 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6315 EVT ArgVT = Outs[i].VT;
6316 EVT OrigVT = Outs[i].ArgVT;
6325 auto ComputePtrOff = [&]() {
6329 ArgOffset =
alignTo(ArgOffset, Alignment);
6340 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6341 GPR_idx = std::min(GPR_idx, NumGPRs);
6348 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6354 if (
Flags.isByVal()) {
6372 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6373 if (GPR_idx != NumGPRs) {
6375 MachinePointerInfo(), VT);
6377 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6379 ArgOffset += PtrByteSize;
6384 if (GPR_idx == NumGPRs &&
Size < 8) {
6386 if (!isLittleEndian) {
6391 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6394 ArgOffset += PtrByteSize;
6403 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6404 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6409 if (
Size < 8 && GPR_idx != NumGPRs) {
6419 if (!isLittleEndian) {
6423 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6429 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6431 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6434 ArgOffset += PtrByteSize;
6440 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6443 if (GPR_idx != NumGPRs) {
6444 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6447 MachinePointerInfo(), ObjType);
6450 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6451 ArgOffset += PtrByteSize;
6453 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6465 if (
Flags.isNest()) {
6467 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6474 if (GPR_idx != NumGPRs) {
6475 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6480 assert(HasParameterArea &&
6481 "Parameter area must exist to pass an argument in memory.");
6483 true, CFlags.IsTailCall,
false, MemOpChains,
6484 TailCallArguments, dl);
6486 ArgOffset += PtrByteSize;
6489 ArgOffset += PtrByteSize;
6502 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6503 bool NeededLoad =
false;
6506 if (FPR_idx != NumFPRs)
6507 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6510 if (!NeedGPROrStack)
6512 else if (GPR_idx != NumGPRs && !IsFastCall) {
6523 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i64, Arg);
6526 }
else if (!
Flags.isInConsecutiveRegs()) {
6527 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6532 }
else if (ArgOffset % PtrByteSize != 0) {
6534 Lo = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, OutVals[i - 1]);
6535 Hi = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6536 if (!isLittleEndian)
6541 }
else if (
Flags.isInConsecutiveRegsLast()) {
6542 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6544 if (!isLittleEndian)
6554 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6562 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6567 assert(HasParameterArea &&
6568 "Parameter area must exist to pass an argument in memory.");
6570 true, CFlags.IsTailCall,
false, MemOpChains,
6571 TailCallArguments, dl);
6578 if (!IsFastCall || NeededLoad) {
6580 Flags.isInConsecutiveRegs()) ? 4 : 8;
6581 if (
Flags.isInConsecutiveRegsLast())
6582 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6602 if (CFlags.IsVarArg) {
6603 assert(HasParameterArea &&
6604 "Parameter area must exist if we have a varargs call.");
6608 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6610 if (VR_idx != NumVRs) {
6612 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6614 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6617 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6618 if (GPR_idx == NumGPRs)
6623 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6625 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6631 if (VR_idx != NumVRs) {
6632 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6637 assert(HasParameterArea &&
6638 "Parameter area must exist to pass an argument in memory.");
6640 true, CFlags.IsTailCall,
true, MemOpChains,
6641 TailCallArguments, dl);
6652 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6653 "mismatch in size of parameter area");
6654 (void)NumBytesActuallyUsed;
6656 if (!MemOpChains.
empty())
6662 if (CFlags.IsIndirect) {
6666 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6671 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6681 if (isELFv2ABI && !CFlags.IsPatchPoint)
6682 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6688 for (
const auto &[
Reg,
N] : RegsToPass) {
6693 if (CFlags.IsTailCall && !IsSibCall)
6697 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6698 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6705 "Required alignment greater than stack alignment.");
6725 return RequiredAlign <= 8;
6730 return RequiredAlign <= 4;
6738 State.getMachineFunction().getSubtarget());
6739 const bool IsPPC64 = Subtarget.isPPC64();
6740 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6741 const Align PtrAlign(PtrSize);
6742 const Align StackAlign(16);
6745 if (ValVT == MVT::f128)
6749 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6750 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6752 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6753 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6756 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6757 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6758 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6763 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6772 if (ByValAlign > StackAlign)
6774 "16 are not supported.");
6777 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6781 if (ByValSize == 0) {
6783 State.getStackSize(), RegVT, LocInfo));
6788 unsigned NextReg = State.getFirstUnallocated(GPRs);
6789 while (NextReg != GPRs.
size() &&
6794 State.AllocateStack(PtrSize, PtrAlign);
6795 assert(
Reg &&
"Alocating register unexpectedly failed.");
6797 NextReg = State.getFirstUnallocated(GPRs);
6800 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6801 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6821 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6825 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6844 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6850 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6852 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6853 if (State.isVarArg()) {
6885 const unsigned VecSize = 16;
6886 const Align VecAlign(VecSize);
6888 if (!State.isVarArg()) {
6891 if (
MCRegister VReg = State.AllocateReg(VR)) {
6898 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6903 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6906 while (NextRegIndex != GPRs.
size() &&
6910 State.AllocateStack(PtrSize, PtrAlign);
6911 assert(
Reg &&
"Allocating register unexpectedly failed.");
6913 NextRegIndex = State.getFirstUnallocated(GPRs);
6921 if (
MCRegister VReg = State.AllocateReg(VR)) {
6924 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6925 State.AllocateReg(GPRs);
6926 State.AllocateStack(VecSize, VecAlign);
6930 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6936 if (NextRegIndex == GPRs.
size()) {
6937 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6945 if (GPRs[NextRegIndex] == PPC::R9) {
6946 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6950 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
6951 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
6952 assert(FirstReg && SecondReg &&
6953 "Allocating R9 or R10 unexpectedly failed.");
6964 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6967 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
6969 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
6984 assert((IsPPC64 || SVT != MVT::i64) &&
6985 "i64 should have been split for 32-bit codegen.");
6993 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
6995 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
6997 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7005 return &PPC::VRRCRegClass;
7018 else if (Flags.isZExt())
7030 "Reg must be a valid argument register!");
7031 return LASize + 4 * (
Reg - PPC::R3);
7036 "Reg must be a valid argument register!");
7037 return LASize + 8 * (
Reg - PPC::X3);
7083SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7090 "Unexpected calling convention!");
7098 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7100 const bool IsPPC64 = Subtarget.isPPC64();
7101 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7107 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7108 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7112 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7113 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7114 uint64_t SaveStackPos = CCInfo.getStackSize();
7116 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7120 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7121 CCValAssign &VA = ArgLocs[
I++];
7126 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7127 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7139 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7141 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7147 MachinePointerInfo(),
Align(PtrByteSize));
7153 unsigned StoreSize =
7155 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7158 auto HandleMemLoc = [&]() {
7161 assert((ValSize <= LocSize) &&
7162 "Object size is larger than size of MemLoc");
7165 if (LocSize > ValSize)
7166 CurArgOffset += LocSize - ValSize;
7168 const bool IsImmutable =
7174 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7208 assert(isVarArg &&
"Only use custom memloc for vararg.");
7211 const unsigned OriginalValNo = VA.
getValNo();
7212 (void)OriginalValNo;
7214 auto HandleCustomVecRegLoc = [&]() {
7215 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7216 "Missing custom RegLoc.");
7219 "Unexpected Val type for custom RegLoc.");
7221 "ValNo mismatch between custom MemLoc and RegLoc.");
7225 Subtarget.hasVSX()));
7232 HandleCustomVecRegLoc();
7233 HandleCustomVecRegLoc();
7237 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7239 "Only 2 custom RegLocs expected for 64-bit codegen.");
7240 HandleCustomVecRegLoc();
7241 HandleCustomVecRegLoc();
7285 const unsigned Size =
7297 if (
Flags.isByVal()) {
7301 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7303 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7311 const TargetRegisterClass *RegClass =
7312 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7314 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7327 CopyFrom.
getValue(1), dl, CopyFrom,
7337 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7340 "RegLocs should be for ByVal argument.");
7342 const CCValAssign RL = ArgLocs[
I++];
7347 if (
Offset != StackSize) {
7349 "Expected MemLoc for remaining bytes.");
7350 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7364 Subtarget.hasVSX()));
7381 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7383 unsigned CallerReservedArea = std::max<unsigned>(
7384 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7390 CallerReservedArea =
7395 int VAListIndex = 0;
7399 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7400 unsigned FixedStackSize =
7401 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7417 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7418 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7420 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7421 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7422 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7428 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7430 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7433 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7434 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7437 MachinePointerInfo MPI =
7447 if (!MemOps.
empty())
7453SDValue PPCTargetLowering::LowerCall_AIX(
7466 "Unexpected calling convention!");
7468 if (CFlags.IsPatchPoint)
7471 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7475 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7482 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7483 const bool IsPPC64 = Subtarget.isPPC64();
7485 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7486 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7487 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7495 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7496 const unsigned NumBytes = std::max<unsigned>(
7497 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7513 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7514 const unsigned ValNo = ArgLocs[
I].getValNo();
7516 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7518 if (
Flags.isByVal()) {
7519 const unsigned ByValSize =
Flags.getByValSize();
7527 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7533 MachinePointerInfo(), VT);
7536 unsigned LoadOffset = 0;
7539 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7542 LoadOffset += PtrByteSize;
7543 const CCValAssign &ByValVA = ArgLocs[
I++];
7545 "Unexpected location for pass-by-value argument.");
7549 if (LoadOffset == ByValSize)
7553 assert(ArgLocs[
I].getValNo() == ValNo &&
7554 "Expected additional location for by-value argument.");
7556 if (ArgLocs[
I].isMemLoc()) {
7557 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7558 const CCValAssign &ByValVA = ArgLocs[
I++];
7559 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7562 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7568 CallSeqStart, MemcpyFlags, DAG, dl);
7577 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7578 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7579 "Unexpected register residue for by-value argument.");
7581 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7585 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7595 "Unexpected load emitted during handling of pass-by-value "
7603 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7608 const CCValAssign &ByValVA = ArgLocs[
I++];
7613 CCValAssign &VA = ArgLocs[
I++];
7638 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7644 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7646 const unsigned OriginalValNo = VA.
getValNo();
7648 unsigned LoadOffset = 0;
7649 auto HandleCustomVecRegLoc = [&]() {
7650 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7651 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7652 "Expected custom RegLoc.");
7653 CCValAssign RegVA = ArgLocs[
I++];
7655 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7661 LoadOffset += PtrByteSize;
7667 HandleCustomVecRegLoc();
7668 HandleCustomVecRegLoc();
7670 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7671 ArgLocs[
I].getValNo() == OriginalValNo) {
7673 "Only 2 custom RegLocs expected for 64-bit codegen.");
7674 HandleCustomVecRegLoc();
7675 HandleCustomVecRegLoc();
7686 DAG.
getStore(Chain, dl, Arg, PtrOff,
7688 Subtarget.getFrameLowering()->getStackAlign()));
7695 "Unexpected register handling for calling convention.");
7701 "Custom register handling only expected for VarArg.");
7706 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7710 else if (Arg.getValueType().getFixedSizeInBits() <
7718 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7719 "Unexpected custom register for argument!");
7720 CCValAssign &GPR1 = VA;
7729 CCValAssign &PeekArg = ArgLocs[
I];
7732 CCValAssign &GPR2 = ArgLocs[
I++];
7740 if (!MemOpChains.
empty())
7745 if (CFlags.IsIndirect) {
7746 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7747 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7748 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7749 const MVT PtrVT = Subtarget.getScalarIntVT();
7750 const unsigned TOCSaveOffset =
7751 Subtarget.getFrameLowering()->getTOCSaveOffset();
7766 for (
auto Reg : RegsToPass) {
7771 const int SPDiff = 0;
7772 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7773 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7781 const Type *RetTy)
const {
7783 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7784 return CCInfo.CheckReturn(
7799 CCInfo.AnalyzeReturn(Outs,
7808 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7809 CCValAssign &VA = RVLocs[i];
7812 SDValue Arg = OutVals[RealResIdx];
7827 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7828 bool isLittleEndian = Subtarget.isLittleEndian();
7831 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7835 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7850 RetOps.push_back(Glue);
7852 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7856PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7861 EVT IntVT =
Op.getValueType();
7865 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7869 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7881 bool isPPC64 = Subtarget.isPPC64();
7882 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7891 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7897 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7902 bool isPPC64 = Subtarget.isPPC64();
7907 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7913 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7923PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7925 bool isPPC64 = Subtarget.isPPC64();
7930 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7936 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
7959 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7961 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
7963 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
7964 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
7971 bool isPPC64 = Subtarget.isPPC64();
7981 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
7983 Op.getOperand(0),
Op.getOperand(1));
7989 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
7990 Op.getOperand(0),
Op.getOperand(1));
7994 if (
Op.getValueType().isVector())
7995 return LowerVectorLoad(
Op, DAG);
7997 assert(
Op.getValueType() == MVT::i1 &&
7998 "Custom lowering only for i1 loads");
8007 MachineMemOperand *MMO =
LD->getMemOperand();
8011 BasePtr, MVT::i8, MMO);
8019 if (
Op.getOperand(1).getValueType().isVector())
8020 return LowerVectorStore(
Op, DAG);
8022 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8023 "Custom lowering only for i1 stores");
8033 MachineMemOperand *MMO =
ST->getMemOperand();
8042 assert(
Op.getValueType() == MVT::i1 &&
8043 "Custom lowering only for i1 results");
8071 EVT TrgVT =
Op.getValueType();
8095 if (SrcSize == 256) {
8106 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8112 SmallVector<int, 16> ShuffV;
8113 if (Subtarget.isLittleEndian())
8114 for (
unsigned i = 0; i < TrgNumElts; ++i)
8117 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8121 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8125 Op1 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op1);
8126 Op2 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op2);
8134 EVT ResVT =
Op.getValueType();
8135 EVT CmpVT =
Op.getOperand(0).getValueType();
8137 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8143 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8156 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8160 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8192 if (
LHS.getValueType() == MVT::f32)
8194 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8196 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8197 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8198 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), Sel1, FV);
8205 if (
LHS.getValueType() == MVT::f32)
8207 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8214 if (
LHS.getValueType() == MVT::f32)
8216 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8217 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), TV, FV);
8228 if (
Cmp.getValueType() == MVT::f32)
8229 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8230 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8232 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8233 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8234 DAG.
getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
8238 if (
Cmp.getValueType() == MVT::f32)
8239 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8240 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8244 if (
Cmp.getValueType() == MVT::f32)
8245 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8246 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8250 if (
Cmp.getValueType() == MVT::f32)
8251 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8252 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8256 if (
Cmp.getValueType() == MVT::f32)
8257 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8258 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8267 case PPCISD::FCTIDZ:
8268 return PPCISD::STRICT_FCTIDZ;
8269 case PPCISD::FCTIWZ:
8270 return PPCISD::STRICT_FCTIWZ;
8271 case PPCISD::FCTIDUZ:
8272 return PPCISD::STRICT_FCTIDUZ;
8273 case PPCISD::FCTIWUZ:
8274 return PPCISD::STRICT_FCTIWUZ;
8276 return PPCISD::STRICT_FCFID;
8277 case PPCISD::FCFIDU:
8278 return PPCISD::STRICT_FCFIDU;
8279 case PPCISD::FCFIDS:
8280 return PPCISD::STRICT_FCFIDS;
8281 case PPCISD::FCFIDUS:
8282 return PPCISD::STRICT_FCFIDUS;
8289 bool IsStrict =
Op->isStrictFPOpcode();
8298 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8300 MVT DestTy =
Op.getSimpleValueType();
8301 assert(Src.getValueType().isFloatingPoint() &&
8302 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8303 DestTy == MVT::i64) &&
8304 "Invalid FP_TO_INT types");
8305 if (Src.getValueType() == MVT::f32) {
8309 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8312 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
8314 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8320 Opc = IsSigned ? PPCISD::FCTIWZ
8321 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8324 assert((IsSigned || Subtarget.hasFPCVT()) &&
8325 "i64 FP_TO_UINT is supported only with FPCVT");
8326 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8328 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8340void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8342 const SDLoc &dl)
const {
8346 bool IsStrict =
Op->isStrictFPOpcode();
8349 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8350 (IsSigned || Subtarget.hasFPCVT());
8353 MachinePointerInfo MPI =
8361 Alignment =
Align(4);
8362 MachineMemOperand *MMO =
8368 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8372 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8373 !Subtarget.isLittleEndian()) {
8382 RLI.Alignment = Alignment;
8390 const SDLoc &dl)
const {
8393 if (
Op->isStrictFPOpcode())
8400 const SDLoc &dl)
const {
8401 bool IsStrict =
Op->isStrictFPOpcode();
8404 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8405 EVT SrcVT = Src.getValueType();
8406 EVT DstVT =
Op.getValueType();
8409 if (SrcVT == MVT::f128)
8410 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8414 if (SrcVT == MVT::ppcf128) {
8415 if (DstVT == MVT::i32) {
8420 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8431 {Op.getOperand(0), Lo, Hi}, Flags);
8434 {Res.getValue(1), Res}, Flags);
8440 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8464 {Chain, Src, FltOfs}, Flags);
8468 {Chain, Val}, Flags);
8471 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8489 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8490 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8493 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8495 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8496 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8507bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8512 if (
Op->isStrictFPOpcode())
8517 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8521 Op.getOperand(0).getValueType())) {
8523 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8528 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8529 LD->isNonTemporal())
8531 if (
LD->getMemoryVT() != MemVT)
8541 RLI.Ptr =
LD->getBasePtr();
8542 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8544 "Non-pre-inc AM on PPC?");
8549 RLI.Chain =
LD->getChain();
8550 RLI.MPI =
LD->getPointerInfo();
8551 RLI.IsDereferenceable =
LD->isDereferenceable();
8552 RLI.IsInvariant =
LD->isInvariant();
8553 RLI.Alignment =
LD->getAlign();
8554 RLI.AAInfo =
LD->getAAInfo();
8555 RLI.Ranges =
LD->getRanges();
8557 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8564bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8565 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8572 if (!Subtarget.hasP9Vector() &&
8576 for (SDUse &Use : Origin->
uses()) {
8579 if (
Use.getResNo() != 0)
8606 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8607 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8608 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8609 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8610 if (
Op->isStrictFPOpcode()) {
8612 Chain =
Op.getOperand(0);
8614 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8616 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8624 const SDLoc &dl)
const {
8625 assert((
Op.getValueType() == MVT::f32 ||
8626 Op.getValueType() == MVT::f64) &&
8627 "Invalid floating point type as target of conversion");
8628 assert(Subtarget.hasFPCVT() &&
8629 "Int to FP conversions with direct moves require FPCVT");
8630 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8631 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8634 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8653 for (
unsigned i = 1; i < NumConcat; ++i)
8660 const SDLoc &dl)
const {
8661 bool IsStrict =
Op->isStrictFPOpcode();
8662 unsigned Opc =
Op.getOpcode();
8663 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8666 "Unexpected conversion type");
8667 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8668 "Supports conversions to v2f64/v4f32 only.");
8672 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8675 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8680 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8682 SmallVector<int, 16> ShuffV;
8683 for (
unsigned i = 0; i < WideNumElts; ++i)
8686 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8687 int SaveElts = FourEltRes ? 4 : 2;
8688 if (Subtarget.isLittleEndian())
8689 for (
int i = 0; i < SaveElts; i++)
8690 ShuffV[i * Stride] = i;
8692 for (
int i = 1; i <= SaveElts; i++)
8693 ShuffV[i * Stride - 1] = i - 1;
8701 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8702 EVT ExtVT = Src.getValueType();
8703 if (Subtarget.hasP9Altivec())
8710 Extend = DAG.
getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
8714 {Op.getOperand(0), Extend}, Flags);
8716 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8724 bool IsStrict =
Op->isStrictFPOpcode();
8725 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8730 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8732 EVT InVT = Src.getValueType();
8733 EVT OutVT =
Op.getValueType();
8736 return LowerINT_TO_FPVector(
Op, DAG, dl);
8739 if (
Op.getValueType() == MVT::f128)
8740 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8743 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8746 if (Src.getValueType() == MVT::i1) {
8758 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8759 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8760 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8762 assert((IsSigned || Subtarget.hasFPCVT()) &&
8763 "UINT_TO_FP is supported only with FPCVT");
8765 if (Src.getValueType() == MVT::i64) {
8780 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8781 !
Op->getFlags().hasApproximateFuncs()) {
8821 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8822 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8823 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8826 }
else if (Subtarget.hasLFIWAX() &&
8827 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8828 MachineMemOperand *MMO =
8830 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8834 Ops, MVT::i32, MMO);
8837 }
else if (Subtarget.hasFPCVT() &&
8838 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8839 MachineMemOperand *MMO =
8841 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8845 Ops, MVT::i32, MMO);
8848 }
else if (((Subtarget.hasLFIWAX() &&
8850 (Subtarget.hasFPCVT() &&
8865 "Expected an i32 store");
8871 RLI.Alignment =
Align(4);
8873 MachineMemOperand *MMO =
8875 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8878 PPCISD::LFIWZX : PPCISD::LFIWAX,
8879 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8880 Ops, MVT::i32, MMO);
8881 Chain =
Bits.getValue(1);
8883 Bits = DAG.
getNode(ISD::BITCAST, dl, MVT::f64, SINT);
8889 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8893 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8902 assert(Src.getValueType() == MVT::i32 &&
8903 "Unhandled INT_TO_FP type in custom expander!");
8913 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8916 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8926 "Expected an i32 store");
8932 RLI.Alignment =
Align(4);
8935 MachineMemOperand *MMO =
8937 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8943 if (ReusingLoad && RLI.ResChain) {
8947 assert(Subtarget.isPPC64() &&
8948 "i32->FP without LFIWAX supported only on PPC64");
8957 Chain, dl, Ext64, FIdx,
8963 MVT::f64, dl, Chain, FIdx,
8972 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8976 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
8993 uint64_t
Mode = CVal->getZExtValue();
8994 assert(
Mode < 4 &&
"Unsupported rounding mode!");
8995 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
8996 if (Subtarget.isISA3_0())
8999 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9000 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9003 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9004 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9006 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9024 if (!Subtarget.isISA3_0()) {
9025 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9029 if (Subtarget.isPPC64()) {
9030 if (Subtarget.isISA3_0()) {
9035 PPC::RLDIMI, Dl, MVT::i64,
9036 {DAG.
getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
9040 NewFPSCR =
SDValue(InsertRN, 0);
9042 NewFPSCR = DAG.
getNode(ISD::BITCAST, Dl, MVT::f64, NewFPSCR);
9047 SDValue Addr = Subtarget.isLittleEndian()
9051 if (Subtarget.isISA3_0()) {
9052 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9054 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9056 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9059 PPC::RLWIMI, Dl, MVT::i32,
9060 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9061 DAG.getTargetConstant(30, Dl, MVT::i32),
9062 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9064 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9067 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9070 if (Subtarget.isISA3_0())
9076 PPC::MTFSF, Dl, MVT::Other,
9104 EVT VT =
Op.getValueType();
9109 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9115 DAG.
getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
9120 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9124 "Stack slot adjustment is valid only on big endian subtargets!");
9127 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9154 EVT VT =
Op.getValueType();
9158 VT ==
Op.getOperand(1).getValueType() &&
9178 SDValue OutOps[] = { OutLo, OutHi };
9183 EVT VT =
Op.getValueType();
9187 VT ==
Op.getOperand(1).getValueType() &&
9207 SDValue OutOps[] = { OutLo, OutHi };
9213 EVT VT =
Op.getValueType();
9216 VT ==
Op.getOperand(1).getValueType() &&
9236 SDValue OutOps[] = { OutLo, OutHi };
9243 EVT VT =
Op.getValueType();
9250 EVT AmtVT =
Z.getValueType();
9260 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9261 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9273 static const MVT VTys[] = {
9274 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9277 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9280 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9285 EVT CanonicalVT = VTys[SplatSize-1];
9298 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9299 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9308 EVT DestVT = MVT::Other) {
9309 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9318 EVT DestVT = MVT::Other) {
9321 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9333 for (
unsigned i = 0; i != 16; ++i)
9336 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9354 EVT VecVT = V->getValueType(0);
9355 bool RightType = VecVT == MVT::v2f64 ||
9356 (HasP8Vector && VecVT == MVT::v4f32) ||
9357 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9361 bool IsSplat =
true;
9362 bool IsLoad =
false;
9368 if (V->isConstant())
9370 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9371 if (V->getOperand(i).isUndef())
9375 if (V->getOperand(i).getOpcode() == ISD::LOAD ||
9377 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9379 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9381 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
9385 if (V->getOperand(i) != Op0 ||
9386 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9389 return !(IsSplat && IsLoad);
9399 (
Op.getValueType() != MVT::f128))
9404 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9407 if (!Subtarget.isLittleEndian())
9410 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9415 while (InputLoad->
getOpcode() == ISD::BITCAST)
9418 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9419 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9422 if (InputLoad->
getOpcode() != ISD::LOAD)
9432 APFloat APFloatToConvert = ArgAPFloat;
9433 bool LosesInfo =
true;
9438 ArgAPFloat = APFloatToConvert;
9460 APFloat APFloatToConvert = ArgAPFloat;
9461 bool LosesInfo =
true;
9465 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9474 EVT Ty =
Op->getValueType(0);
9477 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9486 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9490 if (Ty == MVT::v2i64) {
9493 if (MemVT == MVT::i32) {
9495 Opcode = PPCISD::ZEXT_LD_SPLAT;
9497 Opcode = PPCISD::SEXT_LD_SPLAT;
9505 bool IsLittleEndian) {
9511 APInt ConstValue(VTSize, 0);
9515 unsigned BitPos = 0;
9523 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9524 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9528 for (
unsigned J = 0; J < 16; ++J) {
9530 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9532 if (ExtractValue == 0xFF)
9547 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9549 if (Subtarget.hasP10Vector()) {
9550 APInt BitMask(32, 0);
9556 BitMask != 0 && BitMask != 0xffff) {
9558 MachineSDNode *MSDNode =
9564 SDV = DAG.
getNode(ISD::BITCAST, dl, DVT, SDV);
9570 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9574 APInt APSplatBits, APSplatUndef;
9575 unsigned SplatBitSize;
9577 bool BVNIsConstantSplat =
9579 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9585 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9586 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9589 if ((
Op->getValueType(0) == MVT::v2f64) &&
9592 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9608 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9614 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9622 bool IsSplat64 =
false;
9623 uint64_t SplatBits = 0;
9624 int32_t SextVal = 0;
9625 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9627 if (SplatBitSize <= 32) {
9629 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9630 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9631 bool P9Vector = Subtarget.hasP9Vector();
9632 int32_t
Hi = P9Vector ? 127 : 15;
9633 int32_t
Lo = P9Vector ? -128 : -16;
9634 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9635 SextVal =
static_cast<int32_t
>(SplatBits);
9639 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9640 unsigned NewOpcode = PPCISD::LD_SPLAT;
9646 const SDValue *InputLoad = &
Op.getOperand(0);
9651 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9652 unsigned ElementSize =
9653 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9655 assert(((ElementSize == 2 * MemorySize)
9656 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9657 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9658 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9659 "Unmatched element size and opcode!\n");
9664 unsigned NumUsesOfInputLD = 128 / ElementSize;
9666 if (BVInOp.isUndef())
9681 if (NumUsesOfInputLD == 1 &&
9682 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9683 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9684 Subtarget.hasLFIWAX()))
9692 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9693 Subtarget.isISA3_1() && ElementSize <= 16)
9696 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9698 Subtarget.hasVSX()) {
9705 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9706 LD->getMemoryVT(),
LD->getMemOperand());
9718 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9720 Subtarget.hasP8Vector()))
9726 unsigned SplatSize = SplatBitSize / 8;
9731 if (SplatBits == 0) {
9733 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9735 Op = DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Z);
9745 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9747 Op.getValueType(), DAG, dl);
9749 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9754 if (Subtarget.hasP9Vector() && SplatSize == 1)
9760 if (SextVal >= -16 && SextVal <= 15) {
9763 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9773 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9779 switch (SplatSize) {
9783 IID = Intrinsic::ppc_altivec_vupklsb;
9787 IID = Intrinsic::ppc_altivec_vextsb2w;
9791 IID = Intrinsic::ppc_altivec_vextsb2d;
9798 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9807 if (SextVal >= -32 && SextVal <= 31) {
9812 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9813 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9816 if (VT ==
Op.getValueType())
9819 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), RetVal);
9825 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9835 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9839 static const signed char SplatCsts[] = {
9840 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9841 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9844 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9847 int i = SplatCsts[idx];
9851 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9854 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9856 static const unsigned IIDs[] = {
9857 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9858 Intrinsic::ppc_altivec_vslw
9861 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9865 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9867 static const unsigned IIDs[] = {
9868 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9869 Intrinsic::ppc_altivec_vsrw
9872 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9876 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9877 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9879 static const unsigned IIDs[] = {
9880 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9881 Intrinsic::ppc_altivec_vrlw
9884 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9888 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9890 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9894 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9896 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9900 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9902 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9915 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9916 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9917 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9933 if (LHSID == (1*9+2)*9+3)
return LHS;
9934 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9946 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9947 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9948 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9949 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9952 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9953 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9954 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9955 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9958 for (
unsigned i = 0; i != 16; ++i)
9959 ShufIdxs[i] = (i&3)+0;
9962 for (
unsigned i = 0; i != 16; ++i)
9963 ShufIdxs[i] = (i&3)+4;
9966 for (
unsigned i = 0; i != 16; ++i)
9967 ShufIdxs[i] = (i&3)+8;
9970 for (
unsigned i = 0; i != 16; ++i)
9971 ShufIdxs[i] = (i&3)+12;
9981 OpLHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpLHS);
9982 OpRHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpRHS);
9984 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9992 const unsigned BytesInVector = 16;
9993 bool IsLE = Subtarget.isLittleEndian();
9997 unsigned ShiftElts = 0, InsertAtByte = 0;
10001 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10002 0, 15, 14, 13, 12, 11, 10, 9};
10003 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10004 1, 2, 3, 4, 5, 6, 7, 8};
10006 ArrayRef<int>
Mask =
N->getMask();
10007 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10019 bool FoundCandidate =
false;
10023 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10026 for (
unsigned i = 0; i < BytesInVector; ++i) {
10027 unsigned CurrentElement =
Mask[i];
10030 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10033 bool OtherElementsInOrder =
true;
10036 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10043 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10044 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10045 OtherElementsInOrder =
false;
10052 if (OtherElementsInOrder) {
10059 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10060 : BigEndianShifts[CurrentElement & 0xF];
10061 Swap = CurrentElement < BytesInVector;
10063 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10064 FoundCandidate =
true;
10069 if (!FoundCandidate)
10079 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10081 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10084 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10093 const unsigned NumHalfWords = 8;
10094 const unsigned BytesInVector = NumHalfWords * 2;
10099 bool IsLE = Subtarget.isLittleEndian();
10103 unsigned ShiftElts = 0, InsertAtByte = 0;
10107 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10108 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10111 uint32_t OriginalOrderLow = 0x1234567;
10112 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10115 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10116 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10133 bool FoundCandidate =
false;
10136 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10137 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10139 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10140 uint32_t TargetOrder = 0x0;
10147 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10148 TargetOrder = OriginalOrderLow;
10152 if (MaskOneElt == VINSERTHSrcElem &&
10153 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10154 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10155 FoundCandidate =
true;
10161 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10163 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10165 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10166 : BigEndianShifts[MaskOneElt & 0x7];
10167 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10168 Swap = MaskOneElt < NumHalfWords;
10169 FoundCandidate =
true;
10175 if (!FoundCandidate)
10187 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10190 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10192 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10195 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10197 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10210 auto ShuffleMask = SVN->
getMask();
10225 ShuffleMask = CommutedSV->
getMask();
10234 APInt APSplatValue, APSplatUndef;
10235 unsigned SplatBitSize;
10238 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10250 bool IsLE = Subtarget.isLittleEndian();
10251 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10252 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10253 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10255 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10256 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10257 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10265 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10266 SplatVal |= (SplatVal << SplatBitSize);
10269 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10271 return DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8, SplatNode);
10280 assert(
Op.getValueType() == MVT::v1i128 &&
10281 "Only set v1i128 as custom, other type shouldn't reach here!");
10286 if (SHLAmt % 8 == 0) {
10287 std::array<int, 16>
Mask;
10288 std::iota(
Mask.begin(),
Mask.end(), 0);
10289 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10293 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, Shuffle);
10301 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, OROp);
10318 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10323 V1 =
Op.getOperand(0);
10324 V2 =
Op.getOperand(1);
10326 EVT VT =
Op.getValueType();
10327 bool isLittleEndian = Subtarget.isLittleEndian();
10329 unsigned ShiftElts, InsertAtByte;
10335 bool IsPermutedLoad =
false;
10337 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10347 if (IsPermutedLoad) {
10348 assert((isLittleEndian || IsFourByte) &&
10349 "Unexpected size for permuted load on big endian target");
10350 SplatIdx += IsFourByte ? 2 : 1;
10351 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10352 "Splat of a value outside of the loaded memory");
10357 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10360 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10362 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10366 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10379 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10382 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10391 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10394 if (Subtarget.hasP9Vector() &&
10404 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10406 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10408 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10410 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10412 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10415 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10417 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10418 return SplatInsertNode;
10421 if (Subtarget.hasP9Altivec()) {
10423 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10426 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10430 if (Subtarget.hasVSX() &&
10436 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, V2.
isUndef() ? V1 : V2);
10438 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10440 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
10443 if (Subtarget.hasVSX() &&
10449 DAG.
getNode(ISD::BITCAST, dl, MVT::v2i64, V2.isUndef() ? V1 : V2);
10451 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10453 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
10456 if (Subtarget.hasP9Vector()) {
10460 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveHWord);
10464 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveWord);
10468 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveDWord);
10472 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveQWord);
10476 if (Subtarget.hasVSX()) {
10483 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8,
Splat);
10489 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10490 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Swap);
10497 if (V2.isUndef()) {
10510 (Subtarget.hasP8Altivec() && (
10521 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10531 (Subtarget.hasP8Altivec() && (
10539 ArrayRef<int> PermMask = SVOp->
getMask();
10542 unsigned PFIndexes[4];
10543 bool isFourElementShuffle =
true;
10544 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10546 unsigned EltNo = 8;
10547 for (
unsigned j = 0;
j != 4; ++
j) {
10548 if (PermMask[i * 4 + j] < 0)
10551 unsigned ByteSource = PermMask[i * 4 +
j];
10552 if ((ByteSource & 3) != j) {
10553 isFourElementShuffle =
false;
10558 EltNo = ByteSource / 4;
10559 }
else if (EltNo != ByteSource / 4) {
10560 isFourElementShuffle =
false;
10564 PFIndexes[i] = EltNo;
10572 if (isFourElementShuffle) {
10574 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10575 PFIndexes[2] * 9 + PFIndexes[3];
10578 unsigned Cost = (PFEntry >> 30);
10598 if (V2.isUndef()) V2 = V1;
10600 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10606 unsigned Opcode = PPCISD::VPERM;
10609 bool NeedSwap =
false;
10610 bool isLittleEndian = Subtarget.isLittleEndian();
10611 bool isPPC64 = Subtarget.isPPC64();
10613 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10615 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10616 "XXPERM instead\n");
10617 Opcode = PPCISD::XXPERM;
10625 NeedSwap = !NeedSwap;
10660 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10662 if (V1HasXXSWAPD) {
10665 else if (SrcElt < 16)
10668 if (V2HasXXSWAPD) {
10671 else if (SrcElt > 15)
10680 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10681 if (isLittleEndian)
10683 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10686 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10689 if (V1HasXXSWAPD) {
10693 if (V2HasXXSWAPD) {
10698 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10699 if (ValType != MVT::v2f64)
10705 ShufflesHandledWithVPERM++;
10709 if (Opcode == PPCISD::XXPERM) {
10710 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10712 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10715 dbgs() <<
"With the following permute control vector:\n";
10719 if (Opcode == PPCISD::XXPERM)
10720 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10724 if (isLittleEndian)
10730 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10742 switch (IntrinsicID) {
10746 case Intrinsic::ppc_altivec_vcmpbfp_p:
10750 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10754 case Intrinsic::ppc_altivec_vcmpequb_p:
10758 case Intrinsic::ppc_altivec_vcmpequh_p:
10762 case Intrinsic::ppc_altivec_vcmpequw_p:
10766 case Intrinsic::ppc_altivec_vcmpequd_p:
10767 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10773 case Intrinsic::ppc_altivec_vcmpneb_p:
10774 case Intrinsic::ppc_altivec_vcmpneh_p:
10775 case Intrinsic::ppc_altivec_vcmpnew_p:
10776 case Intrinsic::ppc_altivec_vcmpnezb_p:
10777 case Intrinsic::ppc_altivec_vcmpnezh_p:
10778 case Intrinsic::ppc_altivec_vcmpnezw_p:
10779 if (Subtarget.hasP9Altivec()) {
10780 switch (IntrinsicID) {
10783 case Intrinsic::ppc_altivec_vcmpneb_p:
10786 case Intrinsic::ppc_altivec_vcmpneh_p:
10789 case Intrinsic::ppc_altivec_vcmpnew_p:
10792 case Intrinsic::ppc_altivec_vcmpnezb_p:
10795 case Intrinsic::ppc_altivec_vcmpnezh_p:
10798 case Intrinsic::ppc_altivec_vcmpnezw_p:
10806 case Intrinsic::ppc_altivec_vcmpgefp_p:
10810 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10814 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10818 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10822 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10826 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10827 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10833 case Intrinsic::ppc_altivec_vcmpgtub_p:
10837 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10841 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10845 case Intrinsic::ppc_altivec_vcmpgtud_p:
10846 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10853 case Intrinsic::ppc_altivec_vcmpequq:
10854 case Intrinsic::ppc_altivec_vcmpgtsq:
10855 case Intrinsic::ppc_altivec_vcmpgtuq:
10856 if (!Subtarget.isISA3_1())
10858 switch (IntrinsicID) {
10861 case Intrinsic::ppc_altivec_vcmpequq:
10864 case Intrinsic::ppc_altivec_vcmpgtsq:
10867 case Intrinsic::ppc_altivec_vcmpgtuq:
10874 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10875 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10876 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10877 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10878 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10879 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10880 if (Subtarget.hasVSX()) {
10881 switch (IntrinsicID) {
10882 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10885 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10888 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10891 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10894 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10897 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10907 case Intrinsic::ppc_altivec_vcmpbfp:
10910 case Intrinsic::ppc_altivec_vcmpeqfp:
10913 case Intrinsic::ppc_altivec_vcmpequb:
10916 case Intrinsic::ppc_altivec_vcmpequh:
10919 case Intrinsic::ppc_altivec_vcmpequw:
10922 case Intrinsic::ppc_altivec_vcmpequd:
10923 if (Subtarget.hasP8Altivec())
10928 case Intrinsic::ppc_altivec_vcmpneb:
10929 case Intrinsic::ppc_altivec_vcmpneh:
10930 case Intrinsic::ppc_altivec_vcmpnew:
10931 case Intrinsic::ppc_altivec_vcmpnezb:
10932 case Intrinsic::ppc_altivec_vcmpnezh:
10933 case Intrinsic::ppc_altivec_vcmpnezw:
10934 if (Subtarget.hasP9Altivec())
10935 switch (IntrinsicID) {
10938 case Intrinsic::ppc_altivec_vcmpneb:
10941 case Intrinsic::ppc_altivec_vcmpneh:
10944 case Intrinsic::ppc_altivec_vcmpnew:
10947 case Intrinsic::ppc_altivec_vcmpnezb:
10950 case Intrinsic::ppc_altivec_vcmpnezh:
10953 case Intrinsic::ppc_altivec_vcmpnezw:
10960 case Intrinsic::ppc_altivec_vcmpgefp:
10963 case Intrinsic::ppc_altivec_vcmpgtfp:
10966 case Intrinsic::ppc_altivec_vcmpgtsb:
10969 case Intrinsic::ppc_altivec_vcmpgtsh:
10972 case Intrinsic::ppc_altivec_vcmpgtsw:
10975 case Intrinsic::ppc_altivec_vcmpgtsd:
10976 if (Subtarget.hasP8Altivec())
10981 case Intrinsic::ppc_altivec_vcmpgtub:
10984 case Intrinsic::ppc_altivec_vcmpgtuh:
10987 case Intrinsic::ppc_altivec_vcmpgtuw:
10990 case Intrinsic::ppc_altivec_vcmpgtud:
10991 if (Subtarget.hasP8Altivec())
10996 case Intrinsic::ppc_altivec_vcmpequq_p:
10997 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10998 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10999 if (!Subtarget.isISA3_1())
11001 switch (IntrinsicID) {
11004 case Intrinsic::ppc_altivec_vcmpequq_p:
11007 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11010 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11024 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11028 switch (IntrinsicID) {
11029 case Intrinsic::thread_pointer:
11031 if (Subtarget.isPPC64())
11035 case Intrinsic::ppc_rldimi: {
11036 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11038 APInt
Mask =
Op.getConstantOperandAPInt(4);
11040 return Op.getOperand(2);
11041 if (
Mask.isAllOnes())
11043 uint64_t SH =
Op.getConstantOperandVal(3);
11044 unsigned MB = 0, ME = 0;
11048 if (ME < 63 - SH) {
11051 }
else if (ME > 63 - SH) {
11057 {Op.getOperand(2), Src,
11058 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11059 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11063 case Intrinsic::ppc_rlwimi: {
11064 APInt
Mask =
Op.getConstantOperandAPInt(4);
11066 return Op.getOperand(2);
11067 if (
Mask.isAllOnes())
11070 unsigned MB = 0, ME = 0;
11074 PPC::RLWIMI, dl, MVT::i32,
11075 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11076 DAG.getTargetConstant(MB, dl, MVT::i32),
11077 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11081 case Intrinsic::ppc_rlwnm: {
11082 if (
Op.getConstantOperandVal(3) == 0)
11084 unsigned MB = 0, ME = 0;
11089 {Op.getOperand(1), Op.getOperand(2),
11090 DAG.getTargetConstant(MB, dl, MVT::i32),
11091 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11095 case Intrinsic::ppc_mma_disassemble_acc: {
11096 if (Subtarget.isISAFuture()) {
11097 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11108 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11109 Subtarget.isLittleEndian() ? Value2 :
Value,
11110 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11114 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11115 Subtarget.isLittleEndian() ? Value2 :
Value,
11116 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11120 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11121 Subtarget.isLittleEndian() ?
Value : Value2,
11122 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11126 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11127 Subtarget.isLittleEndian() ?
Value : Value2,
11128 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11135 case Intrinsic::ppc_vsx_disassemble_pair: {
11138 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11140 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11143 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11145 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11146 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11154 case Intrinsic::ppc_mma_build_dmr: {
11157 for (
int i = 1; i < 9; i += 2) {
11160 if (
Hi->getOpcode() == ISD::LOAD)
11162 if (
Lo->getOpcode() == ISD::LOAD)
11165 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11172 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11173 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11175 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11176 "Specify P of 0 or 1 for lower or upper 512 bytes");
11177 unsigned HiLo = Idx->getSExtValue();
11181 Opcode = PPC::DMXXEXTFDMR512;
11182 Subx = PPC::sub_wacc_lo;
11184 Opcode = PPC::DMXXEXTFDMR512_HI;
11185 Subx = PPC::sub_wacc_hi;
11188 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11192 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11196 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11197 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11199 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11200 "Specify a dmr row pair 0-3");
11201 unsigned IdxVal = Idx->getSExtValue();
11205 Subx = PPC::sub_dmrrowp0;
11208 Subx = PPC::sub_dmrrowp1;
11211 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11214 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11218 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11224 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11228 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11229 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11231 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11232 "Specify P of 0 or 1 for lower or upper 512 bytes");
11233 unsigned HiLo = Idx->getSExtValue();
11237 Opcode = PPC::DMXXINSTDMR512;
11238 Subx = PPC::sub_wacc_lo;
11240 Opcode = PPC::DMXXINSTDMR512_HI;
11241 Subx = PPC::sub_wacc_hi;
11251 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11252 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11254 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11255 "Specify a dmr row pair 0-3");
11256 unsigned IdxVal = Idx->getSExtValue();
11260 Subx = PPC::sub_dmrrowp0;
11263 Subx = PPC::sub_dmrrowp1;
11266 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11269 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11278 Op.getOperand(1), DMRRowp,
SubReg),
11282 case Intrinsic::ppc_mma_xxmfacc:
11283 case Intrinsic::ppc_mma_xxmtacc: {
11285 if (!Subtarget.isISAFuture())
11296 case Intrinsic::ppc_unpack_longdouble: {
11298 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11299 "Argument of long double unpack must be 0 or 1!");
11302 Idx->getValueType(0)));
11305 case Intrinsic::ppc_compare_exp_lt:
11306 case Intrinsic::ppc_compare_exp_gt:
11307 case Intrinsic::ppc_compare_exp_eq:
11308 case Intrinsic::ppc_compare_exp_uo: {
11310 switch (IntrinsicID) {
11311 case Intrinsic::ppc_compare_exp_lt:
11314 case Intrinsic::ppc_compare_exp_gt:
11317 case Intrinsic::ppc_compare_exp_eq:
11320 case Intrinsic::ppc_compare_exp_uo:
11326 PPC::SELECT_CC_I4, dl, MVT::i32,
11327 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11328 Op.getOperand(1), Op.getOperand(2)),
11330 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11331 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11334 case Intrinsic::ppc_test_data_class: {
11335 EVT OpVT =
Op.getOperand(1).getValueType();
11336 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11337 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11341 PPC::SELECT_CC_I4, dl, MVT::i32,
11342 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11345 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11346 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11349 case Intrinsic::ppc_fnmsub: {
11350 EVT VT =
Op.getOperand(1).getValueType();
11351 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11355 DAG.
getNode(ISD::FNEG, dl, VT,
Op.getOperand(3))));
11356 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11357 Op.getOperand(2),
Op.getOperand(3));
11359 case Intrinsic::ppc_convert_f128_to_ppcf128:
11360 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11361 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11362 ? RTLIB::CONVERT_PPCF128_F128
11363 : RTLIB::CONVERT_F128_PPCF128;
11365 std::pair<SDValue, SDValue>
Result =
11366 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11370 case Intrinsic::ppc_maxfe:
11371 case Intrinsic::ppc_maxfl:
11372 case Intrinsic::ppc_maxfs:
11373 case Intrinsic::ppc_minfe:
11374 case Intrinsic::ppc_minfl:
11375 case Intrinsic::ppc_minfs: {
11376 EVT VT =
Op.getValueType();
11379 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11380 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11383 if (IntrinsicID == Intrinsic::ppc_minfe ||
11384 IntrinsicID == Intrinsic::ppc_minfl ||
11385 IntrinsicID == Intrinsic::ppc_minfs)
11406 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11407 Op.getOperand(1),
Op.getOperand(2),
11409 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Tmp);
11418 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11426 switch (
Op.getConstantOperandVal(1)) {
11431 Bitx = PPC::sub_eq;
11432 SetOp = PPCISD::SETBC;
11437 Bitx = PPC::sub_eq;
11438 SetOp = PPCISD::SETBCR;
11443 Bitx = PPC::sub_lt;
11444 SetOp = PPCISD::SETBC;
11449 Bitx = PPC::sub_lt;
11450 SetOp = PPCISD::SETBCR;
11455 if (Subtarget.isISA3_1()) {
11460 CR6Reg, SubRegIdx, GlueOp),
11462 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11490 switch (
Op.getConstantOperandVal(ArgStart)) {
11491 case Intrinsic::ppc_cfence: {
11492 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11493 SDValue Val =
Op.getOperand(ArgStart + 1);
11495 if (Ty == MVT::i128) {
11500 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11503 Opcode,
DL, MVT::Other,
11508 case Intrinsic::ppc_mma_disassemble_dmr: {
11510 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11521 if (!Subtarget.isPPC64())
11529 int VectorIndex = 0;
11530 if (Subtarget.isLittleEndian())
11541 assert(
Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
11542 "Expecting an atomic compare-and-swap here.");
11545 EVT MemVT = AtomicNode->getMemoryVT();
11563 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11564 Ops.push_back(AtomicNode->getOperand(i));
11566 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11567 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11569 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11576 EVT MemVT =
N->getMemoryVT();
11578 "Expect quadword atomic operations");
11580 unsigned Opc =
N->getOpcode();
11582 case ISD::ATOMIC_LOAD: {
11585 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11588 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11589 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11590 Ops.push_back(
N->getOperand(
I));
11592 Ops, MemVT,
N->getMemOperand());
11599 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11603 case ISD::ATOMIC_STORE: {
11606 SDVTList Tys = DAG.
getVTList(MVT::Other);
11609 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11615 Ops.push_back(ValLo);
11616 Ops.push_back(ValHi);
11617 Ops.push_back(
N->getOperand(2));
11619 N->getMemOperand());
11631 enum DataClassMask {
11633 DC_NEG_INF = 1 << 4,
11634 DC_POS_INF = 1 << 5,
11635 DC_NEG_ZERO = 1 << 2,
11636 DC_POS_ZERO = 1 << 3,
11637 DC_NEG_SUBNORM = 1,
11638 DC_POS_SUBNORM = 1 << 1,
11641 EVT VT =
Op.getValueType();
11643 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11644 : VT == MVT::f64 ? PPC::XSTSTDCDP
11655 return DAG.
getNOT(Dl, Rev, MVT::i1);
11662 TestOp, Dl, MVT::i32,
11664 DC_NEG_ZERO | DC_POS_ZERO |
11665 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11671 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11677 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11682 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11695 bool IsQuiet = Mask &
fcQNan;
11701 if (VT == MVT::f128) {
11705 QuietMask = 0x8000;
11706 }
else if (VT == MVT::f64) {
11707 if (Subtarget.isPPC64()) {
11718 QuietMask = 0x80000;
11719 }
else if (VT == MVT::f32) {
11721 QuietMask = 0x400000;
11737 unsigned NativeMask = 0;
11739 NativeMask |= DC_NAN;
11741 NativeMask |= DC_NEG_INF;
11743 NativeMask |= DC_POS_INF;
11745 NativeMask |= DC_NEG_ZERO;
11747 NativeMask |= DC_POS_ZERO;
11749 NativeMask |= DC_NEG_SUBNORM;
11751 NativeMask |= DC_POS_SUBNORM;
11754 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11756 TestOp, Dl, MVT::i32,
11765 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11767 uint64_t RHSC =
Op.getConstantOperandVal(1);
11770 if (
LHS.getValueType() == MVT::ppcf128) {
11794 bool Future = Subtarget.isISAFuture();
11797 "Mask predication not supported");
11800 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11801 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11805 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11808 VPLD->getMemoryVT(), VPLD->getMemOperand());
11815 "Mask predication not supported");
11820 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11821 bool Future = Subtarget.isISAFuture();
11822 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11825 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11826 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, VPST->getOperand(1)),
11828 SDVTList Tys = DAG.
getVTList(MVT::Other);
11831 VPST->getMemoryVT(), VPST->getMemOperand());
11842 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11844 int64_t
IntVal =
Op.getConstantOperandVal(0);
11845 if (IntVal >= -16 && IntVal <= 15)
11851 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11852 Op.getValueType() == MVT::v4i32 && Op0.
getOpcode() == ISD::LOAD &&
11856 MachineMemOperand *MMO =
11858 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11861 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
11865 return Bits.getValue(0);
11881 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11886 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11893 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11894 MachinePointerInfo());
11901 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
11907 "Should only be called for ISD::INSERT_VECTOR_ELT");
11911 EVT VT =
Op.getValueType();
11916 if (VT == MVT::v2f64 &&
C)
11919 if (Subtarget.hasP9Vector()) {
11928 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
11934 BitcastLoad,
Op.getOperand(2));
11935 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11939 if (Subtarget.isISA3_1()) {
11940 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
11944 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11945 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11955 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11958 unsigned InsertAtElement =
C->getZExtValue();
11959 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11960 if (Subtarget.isLittleEndian()) {
11961 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11963 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
11975 EVT VT =
Op.getValueType();
11976 bool IsV1024i1 = VT == MVT::v1024i1;
11977 bool IsV2048i1 = VT == MVT::v2048i1;
11981 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
11983 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
11984 "Dense Math support required.");
11985 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
11994 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
11995 MachineMemOperand *NewMMO =
12003 DAG.
getVTList(MVT::v256i1, MVT::Other),
12004 LoadOps, MVT::v256i1, NewMMO);
12009 if (Subtarget.isLittleEndian()) {
12010 std::reverse(Loads.
begin(), Loads.
end());
12011 std::reverse(LoadChains.
begin(), LoadChains.
end());
12020 Loads[2], Loads[3]),
12036 Loads[4], Loads[5]),
12039 Loads[6], Loads[7]),
12041 const SDValue Dmr1Ops[] = {RC, Dmr1Lo, LoSub, Dmr1Hi, HiSub};
12043 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Dmr1Ops), 0);
12049 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12052 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12065 Pairs[2], Pairs[3]),
12071 {RC, Lo, LoSub, Hi, HiSub}),
12081 EVT VT =
Op.getValueType();
12083 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12084 return LowerDMFVectorLoad(
Op, DAG);
12086 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12092 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12093 "Type unsupported without MMA");
12094 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12095 "Type unsupported without paired vector support");
12100 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12102 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12111 if (Subtarget.isLittleEndian()) {
12112 std::reverse(Loads.
begin(), Loads.
end());
12113 std::reverse(LoadChains.
begin(), LoadChains.
end());
12117 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12133 bool IsV1024i1 = VT == MVT::v1024i1;
12134 bool IsV2048i1 = VT == MVT::v2048i1;
12138 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12140 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12141 "Dense Math support required.");
12142 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12144 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12147 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12152 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12156 MachineSDNode *ExtNode =
12160 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12166 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12172 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12178 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12183 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12188 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12193 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12197 MachineSDNode *ExtNode =
12198 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12202 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12205 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12209 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12214 if (Subtarget.isLittleEndian())
12215 std::reverse(Values.
begin(), Values.
end());
12217 SDVTList Tys = DAG.
getVTList(MVT::Other);
12219 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12223 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12224 MachineMemOperand *NewMMO =
12231 Ops[2] = Values[Idx];
12233 MVT::v256i1, NewMMO);
12249 EVT StoreVT =
Value.getValueType();
12251 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12252 return LowerDMFVectorStore(
Op, DAG);
12254 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12260 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12261 "Type unsupported without MMA");
12262 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12263 "Type unsupported without paired vector support");
12266 unsigned NumVecs = 2;
12267 if (StoreVT == MVT::v512i1) {
12268 if (Subtarget.isISAFuture()) {
12269 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12271 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12274 Value2 =
SDValue(ExtNode, 1);
12279 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12280 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12282 if (Subtarget.isISAFuture()) {
12283 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12284 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12285 Idx > 1 ? Value2 :
Value,
12288 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12292 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12306 if (
Op.getValueType() == MVT::v4i32) {
12318 RHSSwap = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHSSwap);
12323 LHS,
RHS, DAG, dl, MVT::v4i32);
12326 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12331 }
else if (
Op.getValueType() == MVT::v16i8) {
12333 bool isLittleEndian = Subtarget.isLittleEndian();
12337 LHS,
RHS, DAG, dl, MVT::v8i16);
12338 EvenParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, EvenParts);
12342 LHS,
RHS, DAG, dl, MVT::v8i16);
12343 OddParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OddParts);
12350 for (
unsigned i = 0; i != 8; ++i) {
12351 if (isLittleEndian) {
12353 Ops[i*2+1] = 2*i+16;
12356 Ops[i*2+1] = 2*i+1+16;
12359 if (isLittleEndian)
12369 bool IsStrict =
Op->isStrictFPOpcode();
12370 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12371 !Subtarget.hasP9Vector())
12380 assert(
Op.getOpcode() == ISD::FP_EXTEND &&
12381 "Should only be called for ISD::FP_EXTEND");
12385 if (
Op.getValueType() != MVT::v2f64 ||
12386 Op.getOperand(0).getValueType() != MVT::v2f32)
12398 "Node should have 2 operands with second one being a constant!");
12410 int DWord = Idx >> 1;
12413 if (Subtarget.isLittleEndian())
12416 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12430 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12432 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12433 LD->getMemoryVT(),
LD->getMemOperand());
12438 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12443 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12445 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12446 LD->getMemoryVT(),
LD->getMemOperand());
12447 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12458 if (STI.useCRBits())
12475 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12476 if (STI.useCRBits())
12484 SDNode *
N =
Op.getNode();
12485 EVT VT =
N->getValueType(0);
12486 EVT CarryType =
N->getValueType(1);
12487 unsigned Opc =
N->getOpcode();
12489 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12491 N->getOperand(0),
N->getOperand(1));
12503 SDNode *
N =
Op.getNode();
12504 unsigned Opc =
N->getOpcode();
12505 EVT VT =
N->getValueType(0);
12506 EVT CarryType =
N->getValueType(1);
12507 SDValue CarryOp =
N->getOperand(2);
12509 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12515 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12529 EVT VT =
Op.getNode()->getValueType(0);
12555 EVT VT =
Op.getNode()->getValueType(0);
12584 EVT OpVT =
A.getValueType();
12585 EVT ResVT =
Op.getValueType();
12591 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12609 switch (
Op.getOpcode()) {
12612 case ISD::FPOW:
return lowerPow(
Op, DAG);
12613 case ISD::FSIN:
return lowerSin(
Op, DAG);
12614 case ISD::FCOS:
return lowerCos(
Op, DAG);
12615 case ISD::FLOG:
return lowerLog(
Op, DAG);
12616 case ISD::FLOG10:
return lowerLog10(
Op, DAG);
12617 case ISD::FEXP:
return lowerExp(
Op, DAG);
12626 case ISD::INIT_TRAMPOLINE:
return LowerINIT_TRAMPOLINE(
Op, DAG);
12627 case ISD::ADJUST_TRAMPOLINE:
return LowerADJUST_TRAMPOLINE(
Op, DAG);
12629 return LowerSSUBO(
Op, DAG);
12631 return LowerSADDO(
Op, DAG);
12633 case ISD::INLINEASM:
12634 case ISD::INLINEASM_BR:
return LowerINLINEASM(
Op, DAG);
12636 case ISD::VASTART:
return LowerVASTART(
Op, DAG);
12637 case ISD::VAARG:
return LowerVAARG(
Op, DAG);
12638 case ISD::VACOPY:
return LowerVACOPY(
Op, DAG);
12640 case ISD::STACKRESTORE:
return LowerSTACKRESTORE(
Op, DAG);
12641 case ISD::DYNAMIC_STACKALLOC:
return LowerDYNAMIC_STACKALLOC(
Op, DAG);
12642 case ISD::GET_DYNAMIC_AREA_OFFSET:
12643 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12650 case ISD::LOAD:
return LowerLOAD(
Op, DAG);
12651 case ISD::STORE:
return LowerSTORE(
Op, DAG);
12663 case ISD::SET_ROUNDING:
12664 return LowerSET_ROUNDING(
Op, DAG);
12671 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12672 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12681 case ISD::FP_EXTEND:
return LowerFP_EXTEND(
Op, DAG);
12684 return LowerFP_ROUND(
Op, DAG);
12691 case ISD::BITCAST:
return LowerBITCAST(
Op, DAG);
12698 return LowerINTRINSIC_VOID(
Op, DAG);
12700 return LowerBSWAP(
Op, DAG);
12701 case ISD::ATOMIC_CMP_SWAP:
12702 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12703 case ISD::ATOMIC_STORE:
12704 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12706 return LowerIS_FPCLASS(
Op, DAG);
12709 return LowerADDSUBO(
Op, DAG);
12712 return LowerADDSUBO_CARRY(
Op, DAG);
12714 return LowerUCMP(
Op, DAG);
12720 if (
Op->getFlags().hasNoFPExcept())
12724 return LowerVP_LOAD(
Op, DAG);
12725 case ISD::VP_STORE:
12726 return LowerVP_STORE(
Op, DAG);
12734 switch (
N->getOpcode()) {
12736 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12737 case ISD::ATOMIC_LOAD: {
12743 case ISD::READCYCLECOUNTER: {
12753 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12756 assert(
N->getValueType(0) == MVT::i1 &&
12757 "Unexpected result type for CTR decrement intrinsic");
12759 N->getValueType(0));
12769 switch (
N->getConstantOperandVal(0)) {
12770 case Intrinsic::ppc_pack_longdouble:
12772 N->getOperand(2),
N->getOperand(1)));
12774 case Intrinsic::ppc_maxfe:
12775 case Intrinsic::ppc_minfe:
12776 case Intrinsic::ppc_fnmsub:
12777 case Intrinsic::ppc_convert_f128_to_ppcf128:
12784 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12787 EVT VT =
N->getValueType(0);
12789 if (VT == MVT::i64) {
12802 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12806 Results.push_back(LoweredValue);
12807 if (
N->isStrictFPOpcode())
12812 if (!
N->getValueType(0).isVector())
12832 case ISD::FP_EXTEND:
12845 return Builder.CreateIntrinsic(Id, {});
12851 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12853 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12854 "Only 8/16/32/64-bit atomic loads supported");
12860 IntID = Intrinsic::ppc_lbarx;
12861 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12864 IntID = Intrinsic::ppc_lharx;
12865 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12868 IntID = Intrinsic::ppc_lwarx;
12871 IntID = Intrinsic::ppc_ldarx;
12875 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12877 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12888 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12889 "Only 8/16/32/64-bit atomic loads supported");
12895 IntID = Intrinsic::ppc_stbcx;
12896 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12899 IntID = Intrinsic::ppc_sthcx;
12900 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12903 IntID = Intrinsic::ppc_stwcx;
12906 IntID = Intrinsic::ppc_stdcx;
12910 if (SZ == 8 || SZ == 16)
12911 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
12913 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
12915 return Builder.CreateXor(
Call, Builder.getInt32(1));
12938 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
12948 unsigned AtomicSize,
12949 unsigned BinOpcode,
12950 unsigned CmpOpcode,
12951 unsigned CmpPred)
const {
12955 auto LoadMnemonic = PPC::LDARX;
12956 auto StoreMnemonic = PPC::STDCX;
12957 switch (AtomicSize) {
12961 LoadMnemonic = PPC::LBARX;
12962 StoreMnemonic = PPC::STBCX;
12963 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12966 LoadMnemonic = PPC::LHARX;
12967 StoreMnemonic = PPC::STHCX;
12968 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12971 LoadMnemonic = PPC::LWARX;
12972 StoreMnemonic = PPC::STWCX;
12975 LoadMnemonic = PPC::LDARX;
12976 StoreMnemonic = PPC::STDCX;
12992 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12994 F->insert(It, loopMBB);
12996 F->insert(It, loop2MBB);
12997 F->insert(It, exitMBB);
13003 Register TmpReg = (!BinOpcode) ? incr :
13004 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13005 : &PPC::GPRCRegClass);
13030 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13035 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13037 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13038 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13039 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13069 switch(
MI.getOpcode()) {
13073 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13074 &
MI.getMF()->getRegInfo());
13098 case PPC::EXTSB8_32_64:
13099 case PPC::EXTSB8_rec:
13100 case PPC::EXTSB_rec:
13103 case PPC::EXTSH8_32_64:
13104 case PPC::EXTSH8_rec:
13105 case PPC::EXTSH_rec:
13107 case PPC::EXTSWSLI:
13108 case PPC::EXTSWSLI_32_64:
13109 case PPC::EXTSWSLI_32_64_rec:
13110 case PPC::EXTSWSLI_rec:
13111 case PPC::EXTSW_32:
13112 case PPC::EXTSW_32_64:
13113 case PPC::EXTSW_32_64_rec:
13114 case PPC::EXTSW_rec:
13117 case PPC::SRAWI_rec:
13118 case PPC::SRAW_rec:
13127 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13137 bool IsSignExtended =
13140 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13141 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13142 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13143 .
addReg(
MI.getOperand(3).getReg());
13144 MI.getOperand(3).setReg(ValueReg);
13148 if (Subtarget.hasPartwordAtomics())
13156 bool is64bit = Subtarget.isPPC64();
13157 bool isLittleEndian = Subtarget.isLittleEndian();
13158 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13169 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13171 F->insert(It, loopMBB);
13173 F->insert(It, loop2MBB);
13174 F->insert(It, exitMBB);
13180 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13183 Register PtrReg = RegInfo.createVirtualRegister(RC);
13184 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13186 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13187 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13188 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13189 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13190 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13191 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13192 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13193 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13194 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13195 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13198 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13225 if (ptrA != ZeroReg) {
13226 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13227 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13235 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13236 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13239 .
addImm(is8bit ? 28 : 27);
13240 if (!isLittleEndian)
13241 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13243 .
addImm(is8bit ? 24 : 16);
13245 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13250 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13260 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13264 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13269 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13273 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13276 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13283 Register SReg = RegInfo.createVirtualRegister(GPRC);
13284 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13288 unsigned ValueReg = SReg;
13289 unsigned CmpReg = Incr2Reg;
13290 if (CmpOpcode == PPC::CMPW) {
13291 ValueReg = RegInfo.createVirtualRegister(GPRC);
13292 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13295 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13296 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13298 ValueReg = ValueSReg;
13330 .
addImm(is8bit ? 24 : 16)
13351 Register DstReg =
MI.getOperand(0).getReg();
13353 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13354 Register mainDstReg =
MRI.createVirtualRegister(RC);
13355 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13358 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13359 "Invalid Pointer Size!");
13407 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13408 Register BufReg =
MI.getOperand(1).getReg();
13410 if (Subtarget.is64BitELFABI()) {
13423 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13425 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13428 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13451 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13454 if (Subtarget.isPPC64()) {
13472 TII->get(PPC::PHI), DstReg)
13476 MI.eraseFromParent();
13490 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13491 "Invalid Pointer Size!");
13494 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13497 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13498 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13512 Register BufReg =
MI.getOperand(0).getReg();
13517 if (PVT == MVT::i64) {
13529 if (PVT == MVT::i64) {
13541 if (PVT == MVT::i64) {
13553 if (PVT == MVT::i64) {
13565 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13575 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13578 MI.eraseFromParent();
13594 "Unexpected stack alignment");
13598 unsigned StackProbeSize =
13601 StackProbeSize &= ~(StackAlign - 1);
13602 return StackProbeSize ? StackProbeSize : StackAlign;
13614 const bool isPPC64 = Subtarget.isPPC64();
13646 MF->
insert(MBBIter, TestMBB);
13647 MF->
insert(MBBIter, BlockMBB);
13648 MF->
insert(MBBIter, TailMBB);
13653 Register DstReg =
MI.getOperand(0).getReg();
13654 Register NegSizeReg =
MI.getOperand(1).getReg();
13656 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13657 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13658 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13664 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13666 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13672 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13673 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13675 .
addDef(ActualNegSizeReg)
13677 .
add(
MI.getOperand(2))
13678 .
add(
MI.getOperand(3));
13684 .
addReg(ActualNegSizeReg);
13687 int64_t NegProbeSize = -(int64_t)ProbeSize;
13689 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13691 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13693 .
addImm(NegProbeSize >> 16);
13697 .
addImm(NegProbeSize & 0xFFFF);
13704 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13706 .
addReg(ActualNegSizeReg)
13708 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13712 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13715 .
addReg(ActualNegSizeReg);
13724 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13725 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13750 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13752 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13753 MaxCallFrameSizeReg)
13754 .
add(
MI.getOperand(2))
13755 .
add(
MI.getOperand(3));
13756 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13758 .
addReg(MaxCallFrameSizeReg);
13764 MBB->addSuccessor(TestMBB);
13767 MI.eraseFromParent();
13769 ++NumDynamicAllocaProbed;
13774 switch (
MI.getOpcode()) {
13775 case PPC::SELECT_CC_I4:
13776 case PPC::SELECT_CC_I8:
13777 case PPC::SELECT_CC_F4:
13778 case PPC::SELECT_CC_F8:
13779 case PPC::SELECT_CC_F16:
13780 case PPC::SELECT_CC_VRRC:
13781 case PPC::SELECT_CC_VSFRC:
13782 case PPC::SELECT_CC_VSSRC:
13783 case PPC::SELECT_CC_VSRC:
13784 case PPC::SELECT_CC_SPE4:
13785 case PPC::SELECT_CC_SPE:
13793 switch (
MI.getOpcode()) {
13794 case PPC::SELECT_I4:
13795 case PPC::SELECT_I8:
13796 case PPC::SELECT_F4:
13797 case PPC::SELECT_F8:
13798 case PPC::SELECT_F16:
13799 case PPC::SELECT_SPE:
13800 case PPC::SELECT_SPE4:
13801 case PPC::SELECT_VRRC:
13802 case PPC::SELECT_VSFRC:
13803 case PPC::SELECT_VSSRC:
13804 case PPC::SELECT_VSRC:
13814 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13815 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13816 if (Subtarget.is64BitELFABI() &&
13817 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13818 !Subtarget.isUsingPCRelativeCalls()) {
13830 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13831 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13833 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13834 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13848 if (Subtarget.hasISEL() &&
13849 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13850 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13851 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13853 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13854 MI.getOpcode() == PPC::SELECT_CC_I8)
13855 Cond.push_back(
MI.getOperand(4));
13858 Cond.push_back(
MI.getOperand(1));
13861 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13862 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13878 F->insert(It, copy0MBB);
13879 F->insert(It, sinkMBB);
13888 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13903 .
addReg(
MI.getOperand(1).getReg())
13906 unsigned SelectPred =
MI.getOperand(4).getImm();
13909 .
addReg(
MI.getOperand(1).getReg())
13926 .
addReg(
MI.getOperand(3).getReg())
13928 .
addReg(
MI.getOperand(2).getReg())
13930 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13946 F->insert(It, readMBB);
13947 F->insert(It, sinkMBB);
13958 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13966 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13968 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13978 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13980 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13982 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13984 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13987 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13989 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13991 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13993 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13996 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13998 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
14000 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
14002 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14005 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14007 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14009 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14011 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14014 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14016 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14018 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14020 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14023 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14025 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14027 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14029 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14032 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14034 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14036 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14038 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14041 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14043 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14045 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14047 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14050 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14052 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14054 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14056 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14059 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14061 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14063 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14065 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14068 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14070 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14072 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14074 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14076 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14077 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14078 (Subtarget.hasPartwordAtomics() &&
14079 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14080 (Subtarget.hasPartwordAtomics() &&
14081 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14082 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14084 auto LoadMnemonic = PPC::LDARX;
14085 auto StoreMnemonic = PPC::STDCX;
14086 switch (
MI.getOpcode()) {
14089 case PPC::ATOMIC_CMP_SWAP_I8:
14090 LoadMnemonic = PPC::LBARX;
14091 StoreMnemonic = PPC::STBCX;
14092 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14094 case PPC::ATOMIC_CMP_SWAP_I16:
14095 LoadMnemonic = PPC::LHARX;
14096 StoreMnemonic = PPC::STHCX;
14097 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14099 case PPC::ATOMIC_CMP_SWAP_I32:
14100 LoadMnemonic = PPC::LWARX;
14101 StoreMnemonic = PPC::STWCX;
14103 case PPC::ATOMIC_CMP_SWAP_I64:
14104 LoadMnemonic = PPC::LDARX;
14105 StoreMnemonic = PPC::STDCX;
14112 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14113 Register oldval =
MI.getOperand(3).getReg();
14114 Register newval =
MI.getOperand(4).getReg();
14120 F->insert(It, loop1MBB);
14121 F->insert(It, loop2MBB);
14122 F->insert(It, exitMBB);
14143 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14169 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14170 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14174 bool is64bit = Subtarget.isPPC64();
14175 bool isLittleEndian = Subtarget.isLittleEndian();
14176 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14181 Register oldval =
MI.getOperand(3).getReg();
14182 Register newval =
MI.getOperand(4).getReg();
14188 F->insert(It, loop1MBB);
14189 F->insert(It, loop2MBB);
14190 F->insert(It, exitMBB);
14197 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14200 Register PtrReg = RegInfo.createVirtualRegister(RC);
14201 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14203 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14204 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14205 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14206 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14207 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14208 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14209 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14210 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14211 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14212 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14213 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14215 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14216 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14217 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14248 if (ptrA != ZeroReg) {
14249 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14250 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14259 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14260 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
14263 .
addImm(is8bit ? 28 : 27);
14264 if (!isLittleEndian)
14265 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14267 .
addImm(is8bit ? 24 : 16);
14269 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14274 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14279 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14282 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14289 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14293 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14296 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14299 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14304 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14321 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14345 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14355 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14370 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14378 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14379 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14380 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14381 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14382 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14383 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14386 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14387 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14390 Register Dest = RegInfo.createVirtualRegister(
14391 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14395 .
addReg(
MI.getOperand(1).getReg())
14398 MI.getOperand(0).getReg())
14399 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14400 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14403 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14406 MI.getOperand(0).getReg())
14408 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14410 unsigned Imm =
MI.getOperand(1).getImm();
14413 MI.getOperand(0).getReg())
14415 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14417 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14420 if (
MRI.use_empty(OldFPSCRReg))
14421 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14423 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14434 unsigned Mode =
MI.getOperand(1).getImm();
14435 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14439 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14442 }
else if (
MI.getOpcode() == PPC::SETRND) {
14450 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14451 if (Subtarget.hasDirectMove()) {
14452 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14456 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14459 if (RC == &PPC::F8RCRegClass) {
14461 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14462 "Unsupported RegClass.");
14464 StoreOp = PPC::STFD;
14468 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14469 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14470 "Unsupported RegClass.");
14503 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14506 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14518 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14520 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14522 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14523 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14528 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14529 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14534 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14535 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14541 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14542 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14551 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14555 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14556 if (
MRI.use_empty(OldFPSCRReg))
14557 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14559 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14562 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14568 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14569 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14571 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14578 .
addUse(Src, 0, PPC::sub_gp8_x1);
14581 .
addUse(Src, 0, PPC::sub_gp8_x0);
14582 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14583 MI.getOpcode() == PPC::STQX_PSEUDO) {
14589 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14595 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14596 :
TII->get(PPC::STQ))
14600 }
else if (
MI.getOpcode() == PPC::LWAT_PSEUDO ||
14601 MI.getOpcode() == PPC::LDAT_PSEUDO) {
14603 Register DstReg =
MI.getOperand(0).getReg();
14604 Register PtrReg =
MI.getOperand(1).getReg();
14605 Register ValReg =
MI.getOperand(2).getReg();
14606 unsigned FC =
MI.getOperand(3).getImm();
14607 bool IsLwat =
MI.getOpcode() == PPC::LWAT_PSEUDO;
14608 Register Val64 =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14610 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::SUBREG_TO_REG), Val64)
14617 Register G8rPair =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14618 Register UndefG8r =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14619 BuildMI(*BB,
MI,
DL,
TII->get(TargetOpcode::IMPLICIT_DEF), UndefG8r);
14622 .
addImm(PPC::sub_gp8_x0)
14624 .
addImm(PPC::sub_gp8_x1);
14626 Register PairResult =
MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14627 BuildMI(*BB,
MI,
DL,
TII->get(IsLwat ? PPC::LWAT : PPC::LDAT), PairResult)
14631 Register Result64 =
MRI.createVirtualRegister(&PPC::G8RCRegClass);
14633 .
addReg(PairResult, 0, PPC::sub_gp8_x0);
14636 .
addReg(Result64, 0, PPC::sub_32);
14644 MI.eraseFromParent();
14657 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14660 return RefinementSteps;
14666 EVT VT =
Op.getValueType();
14669 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14693PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14696 EVT VT =
Op.getValueType();
14697 if (VT != MVT::f64 &&
14698 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14701 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14705 int Enabled,
int &RefinementSteps,
14706 bool &UseOneConstNR,
14707 bool Reciprocal)
const {
14709 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14710 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14711 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14712 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14718 UseOneConstNR = !Subtarget.needsTwoConstNR();
14719 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14726 int &RefinementSteps)
const {
14728 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14729 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14730 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14731 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14734 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14750 switch (Subtarget.getCPUDirective()) {
14777 unsigned Bytes,
int Dist,
14791 if (FS != BFS || FS != (
int)Bytes)
return false;
14796 int64_t Offset1 = 0, Offset2 = 0;
14799 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14809 if (isGA1 && isGA2 && GV1 == GV2)
14810 return Offset1 == (Offset2 + Dist*Bytes);
14817 unsigned Bytes,
int Dist,
14820 EVT VT = LS->getMemoryVT();
14827 switch (
N->getConstantOperandVal(1)) {
14828 default:
return false;
14829 case Intrinsic::ppc_altivec_lvx:
14830 case Intrinsic::ppc_altivec_lvxl:
14831 case Intrinsic::ppc_vsx_lxvw4x:
14832 case Intrinsic::ppc_vsx_lxvw4x_be:
14835 case Intrinsic::ppc_vsx_lxvd2x:
14836 case Intrinsic::ppc_vsx_lxvd2x_be:
14839 case Intrinsic::ppc_altivec_lvebx:
14842 case Intrinsic::ppc_altivec_lvehx:
14845 case Intrinsic::ppc_altivec_lvewx:
14855 switch (
N->getConstantOperandVal(1)) {
14856 default:
return false;
14857 case Intrinsic::ppc_altivec_stvx:
14858 case Intrinsic::ppc_altivec_stvxl:
14859 case Intrinsic::ppc_vsx_stxvw4x:
14862 case Intrinsic::ppc_vsx_stxvd2x:
14865 case Intrinsic::ppc_vsx_stxvw4x_be:
14868 case Intrinsic::ppc_vsx_stxvd2x_be:
14871 case Intrinsic::ppc_altivec_stvebx:
14874 case Intrinsic::ppc_altivec_stvehx:
14877 case Intrinsic::ppc_altivec_stvewx:
14894 SDValue Chain = LD->getChain();
14895 EVT VT = LD->getMemoryVT();
14904 while (!Queue.empty()) {
14905 SDNode *ChainNext = Queue.pop_back_val();
14906 if (!Visited.
insert(ChainNext).second)
14913 if (!Visited.
count(ChainLD->getChain().getNode()))
14914 Queue.push_back(ChainLD->getChain().getNode());
14916 for (
const SDUse &O : ChainNext->
ops())
14917 if (!Visited.
count(O.getNode()))
14918 Queue.push_back(O.getNode());
14920 LoadRoots.
insert(ChainNext);
14931 for (
SDNode *
I : LoadRoots) {
14932 Queue.push_back(
I);
14934 while (!Queue.empty()) {
14935 SDNode *LoadRoot = Queue.pop_back_val();
14936 if (!Visited.
insert(LoadRoot).second)
14948 Queue.push_back(U);
14981 auto Final = Shifted;
14992 DAGCombinerInfo &DCI)
const {
14995 SelectionDAG &DAG = DCI.DAG;
15000 if (!DCI.isAfterLegalizeDAG())
15005 for (
const SDNode *U :
N->users())
15010 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15014 if (OpSize <
Size) {
15032 DAGCombinerInfo &DCI)
const {
15033 SelectionDAG &DAG = DCI.DAG;
15036 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15047 N->getValueType(0) != MVT::i1)
15050 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15051 N->getOperand(0).getValueType() != MVT::i64)
15061 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15072 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15095 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15096 N->getOperand(0).getOpcode() !=
ISD::OR &&
15097 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15107 N->getOperand(1).getOpcode() !=
ISD::AND &&
15108 N->getOperand(1).getOpcode() !=
ISD::OR &&
15109 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15120 SmallPtrSet<SDNode *, 16> Visited;
15122 for (
unsigned i = 0; i < 2; ++i) {
15126 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15138 while (!BinOps.
empty()) {
15146 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15180 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15184 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15185 if (User !=
N && !Visited.
count(User))
15194 if (
User->getOperand(0) == Inputs[i])
15197 if (
User->getOperand(0) == Inputs[i] ||
15198 User->getOperand(1) == Inputs[i])
15204 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15205 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15206 if (User !=
N && !Visited.
count(User))
15215 if (
User->getOperand(0) == PromOps[i])
15218 if (
User->getOperand(0) == PromOps[i] ||
15219 User->getOperand(1) == PromOps[i])
15226 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15235 std::list<HandleSDNode> PromOpHandles;
15236 for (
auto &PromOp : PromOps)
15237 PromOpHandles.emplace_back(PromOp);
15244 while (!PromOpHandles.empty()) {
15245 SDValue PromOp = PromOpHandles.back().getValue();
15246 PromOpHandles.pop_back();
15255 PromOpHandles.emplace_front(PromOp);
15269 default:
C = 0;
break;
15282 PromOpHandles.emplace_front(PromOp);
15289 for (
unsigned i = 0; i < 2; ++i)
15299 return N->getOperand(0);
15307 DAGCombinerInfo &DCI)
const {
15308 SelectionDAG &DAG = DCI.DAG;
15325 if (
N->getValueType(0) != MVT::i32 &&
15326 N->getValueType(0) != MVT::i64)
15329 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15330 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15333 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15334 N->getOperand(0).getOpcode() !=
ISD::OR &&
15335 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15342 SmallPtrSet<SDNode *, 16> Visited;
15346 while (!BinOps.
empty()) {
15354 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15380 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15385 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15390 if (User !=
N && !Visited.
count(User))
15396 if (
User->getOperand(0) == Inputs[i])
15397 SelectTruncOp[0].
insert(std::make_pair(User,
15398 User->getOperand(0).getValueType()));
15400 if (
User->getOperand(0) == Inputs[i])
15401 SelectTruncOp[0].
insert(std::make_pair(User,
15402 User->getOperand(0).getValueType()));
15403 if (
User->getOperand(1) == Inputs[i])
15404 SelectTruncOp[1].
insert(std::make_pair(User,
15405 User->getOperand(1).getValueType()));
15410 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15412 if (User !=
N && !Visited.
count(User))
15418 if (
User->getOperand(0) == PromOps[i])
15419 SelectTruncOp[0].
insert(std::make_pair(User,
15420 User->getOperand(0).getValueType()));
15422 if (
User->getOperand(0) == PromOps[i])
15423 SelectTruncOp[0].
insert(std::make_pair(User,
15424 User->getOperand(0).getValueType()));
15425 if (
User->getOperand(1) == PromOps[i])
15426 SelectTruncOp[1].
insert(std::make_pair(User,
15427 User->getOperand(1).getValueType()));
15432 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15433 bool ReallyNeedsExt =
false;
15437 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15442 Inputs[i].getOperand(0).getValueSizeInBits();
15443 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15448 OpBits-PromBits))) ||
15451 (OpBits-(PromBits-1)))) {
15452 ReallyNeedsExt =
true;
15460 std::list<HandleSDNode> PromOpHandles;
15461 for (
auto &PromOp : PromOps)
15462 PromOpHandles.emplace_back(PromOp);
15466 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15473 SDValue InSrc = Inputs[i].getOperand(0);
15491 while (!PromOpHandles.empty()) {
15493 PromOpHandles.pop_back();
15497 default:
C = 0;
break;
15510 PromOpHandles.emplace_front(PromOp);
15520 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15522 PromOpHandles.emplace_front(PromOp);
15530 for (
unsigned i = 0; i < 2; ++i) {
15548 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15549 if (SI0 != SelectTruncOp[0].
end())
15551 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15552 if (SI1 != SelectTruncOp[1].
end())
15561 if (!ReallyNeedsExt)
15562 return N->getOperand(0);
15569 N->getValueSizeInBits(0), PromBits),
15570 dl,
N->getValueType(0)));
15573 "Invalid extension type");
15576 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15586 auto isValidForConvert = [](
SDValue &Operand) {
15605 if (LoadNode->isVolatile())
15626 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15636 "CC mus be ISD::SETNE or ISD::SETEQ");
15638 auto getV16i8Load = [&](
const SDValue &Operand) {
15642 assert(Operand.
getOpcode() == ISD::LOAD &&
"Must be LoadSDNode here.");
15645 return DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15646 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15685 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15686 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15689 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15692 IntrID, CRSel, LHSVec, RHSVec);
15695 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15713 auto IsAndWithOne = [](
SDValue &V) {
15724 auto IsCompareWithZero = [](
SDValue &V) {
15731 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15732 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15749 auto MakeXor1 = [&](
SDValue V) {
15750 EVT VT = V.getValueType();
15757 return MakeXor1(
LHS);
15760 return MakeXor1(
RHS);
15766 DAGCombinerInfo &DCI)
const {
15768 "Should be called with a SETCC node");
15790 SelectionDAG &DAG = DCI.DAG;
15791 EVT VT =
N->getValueType(0);
15792 EVT OpVT =
LHS.getValueType();
15814 return DAGCombineTruncBoolExt(
N, DCI);
15821 Op.getValueType() == MVT::f64;
15833combineElementTruncationToVectorTruncation(
SDNode *
N,
15834 DAGCombinerInfo &DCI)
const {
15836 "Should be called with a BUILD_VECTOR node");
15838 SelectionDAG &DAG = DCI.DAG;
15841 SDValue FirstInput =
N->getOperand(0);
15843 "The input operand must be an fp-to-int conversion.");
15848 if (FirstConversion == PPCISD::FCTIDZ ||
15849 FirstConversion == PPCISD::FCTIDUZ ||
15850 FirstConversion == PPCISD::FCTIWZ ||
15851 FirstConversion == PPCISD::FCTIWUZ) {
15852 bool IsSplat =
true;
15853 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
15854 FirstConversion == PPCISD::FCTIWUZ;
15857 EVT TargetVT =
N->getValueType(0);
15858 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15859 SDValue NextOp =
N->getOperand(i);
15860 if (NextOp.
getOpcode() != PPCISD::MFVSR)
15863 if (NextConversion != FirstConversion)
15871 if (
N->getOperand(i) != FirstInput)
15882 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15883 SDValue In =
N->getOperand(i).getOperand(0);
15893 Ops.push_back(Trunc);
15896 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
15900 if (FirstConversion == PPCISD::FCTIDZ ||
15901 FirstConversion == PPCISD::FCTIWZ)
15906 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15908 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15926 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
15930 if (FullVal == BasePattern)
15931 return std::make_tuple(Uim,
uint8_t{0});
15934 if (FullVal ==
APInt(128, 1))
15935 return std::make_tuple(Uim,
uint8_t{127});
15937 return std::nullopt;
15957 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
15961 EVT VT =
Op.getValueType();
15962 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
15976 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
15986 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
15990 uint64_t ElemValue =
C->getZExtValue();
15994 ElemValue &= ((1ULL << ElemBits) - 1);
15998 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16001 APInt ElemAPInt(128, ElemValue);
16002 ElemAPInt <<= BitPos;
16005 FullVal |= ElemAPInt;
16012 const auto &[Uim, ShiftAmount] = *UIMOpt;
16016 if (ShiftAmount == 0) {
16021 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16022 LxvkqInstr.
dump());
16026 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16038 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16041 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16057 "Should be called with a BUILD_VECTOR node");
16062 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16065 bool InputsAreConsecutiveLoads =
true;
16066 bool InputsAreReverseConsecutive =
true;
16067 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16068 SDValue FirstInput =
N->getOperand(0);
16069 bool IsRoundOfExtLoad =
false;
16078 if ((!IsRoundOfExtLoad && FirstInput.
getOpcode() != ISD::LOAD) ||
16079 N->getNumOperands() == 1)
16082 if (!IsRoundOfExtLoad)
16087 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16089 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16092 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16094 if (NextInput.
getOpcode() != ISD::LOAD)
16098 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16109 InputsAreConsecutiveLoads =
false;
16111 InputsAreReverseConsecutive =
false;
16114 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16119 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16120 "The loads cannot be both consecutive and reverse consecutive.");
16124 if (InputsAreConsecutiveLoads) {
16125 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16129 ReturnSDVal = WideLoad;
16130 }
else if (InputsAreReverseConsecutive) {
16132 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16137 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16145 for (
auto *LD : InputLoads)
16147 return ReturnSDVal;
16158 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16164 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16166 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16168 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16169 CorrectElems = CorrectElems >> 8;
16170 Elems = Elems >> 8;
16177 EVT VT =
N->getValueType(0);
16181 Input.getValueType().getVectorElementType(),
16215 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16241 Elems = Elems << 8;
16250 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16251 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16258 int TgtElemArrayIdx;
16259 int InputSize =
Input.getValueType().getScalarSizeInBits();
16260 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16261 if (InputSize + OutputSize == 40)
16262 TgtElemArrayIdx = 0;
16263 else if (InputSize + OutputSize == 72)
16264 TgtElemArrayIdx = 1;
16265 else if (InputSize + OutputSize == 48)
16266 TgtElemArrayIdx = 2;
16267 else if (InputSize + OutputSize == 80)
16268 TgtElemArrayIdx = 3;
16269 else if (InputSize + OutputSize == 96)
16270 TgtElemArrayIdx = 4;
16274 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16276 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16277 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16278 if (Elems != CorrectElems) {
16294 if (
N->getValueType(0) != MVT::v1i128)
16297 SDValue Operand =
N->getOperand(0);
16304 EVT MemoryType = LD->getMemoryVT();
16308 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16309 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16312 if (!ValidLDType ||
16318 LD->getChain(), LD->getBasePtr(),
16322 DAG.
getVTList(MVT::v1i128, MVT::Other),
16323 LoadOps, MemoryType, LD->getMemOperand());
16327 DAGCombinerInfo &DCI)
const {
16329 "Should be called with a BUILD_VECTOR node");
16331 SelectionDAG &DAG = DCI.DAG;
16334 if (!Subtarget.hasVSX())
16341 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16342 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16357 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16366 if (Subtarget.isISA3_1()) {
16372 if (
N->getValueType(0) != MVT::v2f64)
16383 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16394 if (!Ext1Op || !Ext2Op)
16403 if (FirstElem == 0 && SecondElem == 1)
16404 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16405 else if (FirstElem == 2 && SecondElem == 3)
16406 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16412 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16413 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16418 DAGCombinerInfo &DCI)
const {
16421 "Need an int -> FP conversion node here");
16426 SelectionDAG &DAG = DCI.DAG;
16432 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16434 if (!
Op.getOperand(0).getValueType().isSimple())
16436 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16437 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16440 SDValue FirstOperand(
Op.getOperand(0));
16441 bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
16442 (FirstOperand.getValueType() == MVT::i8 ||
16443 FirstOperand.getValueType() == MVT::i16);
16444 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16446 bool DstDouble =
Op.getValueType() == MVT::f64;
16447 unsigned ConvOp =
Signed ?
16448 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16449 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16454 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16457 Ops, MVT::i8, LDN->getMemOperand());
16462 SDValue ExtOps[] = { Ld, WidthConst };
16464 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16466 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16474 if (
Op.getOperand(0).getValueType() == MVT::i32)
16478 "UINT_TO_FP is supported only with FPCVT");
16482 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16487 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16494 Subtarget.hasFPCVT()) ||
16496 SDValue Src =
Op.getOperand(0).getOperand(0);
16497 if (Src.getValueType() == MVT::f32) {
16498 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
16499 DCI.AddToWorklist(Src.getNode());
16500 }
else if (Src.getValueType() != MVT::f64) {
16512 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16515 DCI.AddToWorklist(
FP.getNode());
16539 switch (
N->getOpcode()) {
16544 Chain = LD->getChain();
16545 Base = LD->getBasePtr();
16546 MMO = LD->getMemOperand();
16565 MVT VecTy =
N->getValueType(0).getSimpleVT();
16573 Chain = Load.getValue(1);
16575 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16579 if (VecTy != MVT::v2f64) {
16606 switch (
N->getOpcode()) {
16611 Chain = ST->getChain();
16612 Base = ST->getBasePtr();
16613 MMO = ST->getMemOperand();
16633 SDValue Src =
N->getOperand(SrcOpnd);
16634 MVT VecTy = Src.getValueType().getSimpleVT();
16637 if (VecTy != MVT::v2f64) {
16638 Src = DAG.
getNode(ISD::BITCAST, dl, MVT::v2f64, Src);
16643 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16649 StoreOps, VecTy, MMO);
16656 DAGCombinerInfo &DCI)
const {
16659 unsigned Opcode =
N->getOperand(1).getOpcode();
16661 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16665 &&
"Not a FP_TO_INT Instruction!");
16667 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16668 EVT Op1VT =
N->getOperand(1).getValueType();
16671 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16675 bool ValidTypeForStoreFltAsInt =
16676 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16677 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16680 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16683 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16691 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16706 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16707 for (
int i = 1, e = Mask.size(); i < e; i++) {
16708 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16710 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16712 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16723 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16724 FirstOp =
Op.getOperand(i);
16730 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16731 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16739 if (
Op.getOpcode() != ISD::BITCAST)
16741 Op =
Op.getOperand(0);
16757 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16758 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16760 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16762 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16763 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16764 int Idx = ShuffV[
I];
16765 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16766 ShuffV[
I] += LHSEltFixup;
16767 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16768 ShuffV[
I] += RHSEltFixup;
16779 SDLoc dl(OrigSToV);
16782 "Expecting a SCALAR_TO_VECTOR here");
16795 "Cannot produce a permuted scalar_to_vector for one element vector");
16797 unsigned ResultInElt = NumElts / 2;
16803 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
16808 int HalfVec,
int LHSLastElementDefined,
16809 int RHSLastElementDefined) {
16810 for (
int Index : ShuffV) {
16814 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16815 (Index > LHSLastElementDefined))
16818 if ((RHSLastElementDefined >= 0) &&
16819 (Index > HalfVec + RHSLastElementDefined))
16826 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16827 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16843 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16844 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16847 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16848 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16849 return SToVPermuted;
16869 int NumElts =
LHS.getValueType().getVectorNumElements();
16872 bool IsLittleEndian = Subtarget.isLittleEndian();
16879 if (!Subtarget.hasDirectMove())
16895 SmallVector<int, 16> ShuffV(Mask);
16898 if (SToVLHS || SToVRHS) {
16901 int ShuffleNumElts = ShuffV.
size();
16902 int HalfVec = ShuffleNumElts / 2;
16908 unsigned LHSNumValidElts = HalfVec;
16909 unsigned RHSNumValidElts = HalfVec;
16914 int LHSFirstElt = 0;
16915 int RHSFirstElt = ShuffleNumElts;
16916 int LHSLastElt = -1;
16917 int RHSLastElt = -1;
16925 int LHSScalarSize = 0;
16926 int RHSScalarSize = 0;
16929 if (!IsLittleEndian && LHSScalarSize >= 64)
16934 if (!IsLittleEndian && RHSScalarSize >= 64)
16937 if (LHSScalarSize != 0)
16939 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
16940 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
16941 if (RHSScalarSize != 0)
16943 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
16944 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
16955 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
16956 LHSNumValidElts, RHSNumValidElts, Subtarget);
16982 if (IsLittleEndian) {
16985 if (Mask[0] < NumElts)
16986 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16990 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16995 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
16999 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17004 if (Mask[0] < NumElts)
17005 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17009 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17014 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17018 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17028 if (IsLittleEndian)
17037 DAGCombinerInfo &DCI)
const {
17039 "Not a reverse memop pattern!");
17041 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17044 auto I =
Mask.rbegin();
17045 auto E =
Mask.rend();
17047 for (;
I !=
E; ++
I) {
17055 SelectionDAG &DAG = DCI.DAG;
17058 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17064 if (!Subtarget.hasP9Vector())
17067 if(!IsElementReverse(SVN))
17070 if (LSBase->
getOpcode() == ISD::LOAD) {
17074 for (SDUse &Use : LSBase->
uses())
17075 if (
Use.getResNo() == 0 &&
17082 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17086 if (LSBase->
getOpcode() == ISD::STORE) {
17097 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17106 if (IntrinsicID == Intrinsic::ppc_stdcx)
17108 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17110 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17112 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17121 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17125 if (
LHS->getOpcode() == PPCISD::ADDE &&
17138 switch (
N->getOpcode()) {
17141 return combineADD(
N, DCI);
17167 return combineSHL(
N, DCI);
17169 return combineSRA(
N, DCI);
17171 return combineSRL(
N, DCI);
17173 return combineMUL(
N, DCI);
17175 case PPCISD::FNMSUB:
17176 return combineFMALike(
N, DCI);
17179 return N->getOperand(0);
17183 return N->getOperand(0);
17189 return N->getOperand(0);
17195 return DAGCombineExtBoolTrunc(
N, DCI);
17197 return combineTRUNCATE(
N, DCI);
17199 if (
SDValue CSCC = combineSetCC(
N, DCI))
17203 return DAGCombineTruncBoolExt(
N, DCI);
17206 return combineFPToIntToFP(
N, DCI);
17215 EVT Op1VT =
N->getOperand(1).getValueType();
17216 unsigned Opcode =
N->getOperand(1).getOpcode();
17220 SDValue Val = combineStoreFPToInt(
N, DCI);
17234 N->getOperand(1).getNode()->hasOneUse() &&
17235 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17236 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17244 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17251 if (Op1VT.
bitsGT(mVT)) {
17256 if (Op1VT == MVT::i64)
17261 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17281 ST->getBasePtr(), ST->getOffset(), MemVT,
17282 ST->getMemOperand(), ST->getAddressingMode(),
17286 return ST->isUnindexed()
17295 if (Subtarget.needsSwapsForVSXMemOps() &&
17296 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17297 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17304 EVT VT = LD->getValueType(0);
17310 if (Subtarget.needsSwapsForVSXMemOps() &&
17311 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17312 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17323 auto ReplaceTwoFloatLoad = [&]() {
17324 if (VT != MVT::i64)
17339 if (!LD->hasNUsesOfValue(2, 0))
17342 auto UI = LD->user_begin();
17343 while (UI.getUse().getResNo() != 0) ++UI;
17345 while (UI.getUse().getResNo() != 0) ++UI;
17346 SDNode *RightShift = *UI;
17354 if (RightShift->getOpcode() !=
ISD::SRL ||
17356 RightShift->getConstantOperandVal(1) != 32 ||
17357 !RightShift->hasOneUse())
17360 SDNode *Trunc2 = *RightShift->user_begin();
17369 if (Bitcast->getOpcode() != ISD::BITCAST ||
17370 Bitcast->getValueType(0) != MVT::f32)
17372 if (Bitcast2->
getOpcode() != ISD::BITCAST ||
17376 if (Subtarget.isLittleEndian())
17382 SDValue BasePtr = LD->getBasePtr();
17383 if (LD->isIndexed()) {
17385 "Non-pre-inc AM on PPC?");
17393 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17394 LD->getPointerInfo(), LD->getAlign(),
17395 MMOFlags, LD->getAAInfo());
17401 LD->getPointerInfo().getWithOffset(4),
17404 if (LD->isIndexed()) {
17418 if (ReplaceTwoFloatLoad())
17421 EVT MemVT = LD->getMemoryVT();
17424 if (LD->isUnindexed() && VT.
isVector() &&
17427 !Subtarget.hasP8Vector() &&
17428 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17429 VT == MVT::v4f32))) &&
17430 LD->getAlign() < ABIAlignment) {
17432 SDValue Chain = LD->getChain();
17433 SDValue Ptr = LD->getBasePtr();
17434 bool isLittleEndian = Subtarget.isLittleEndian();
17461 MVT PermCntlTy, PermTy, LDTy;
17462 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17463 : Intrinsic::ppc_altivec_lvsl;
17464 IntrLD = Intrinsic::ppc_altivec_lvx;
17465 IntrPerm = Intrinsic::ppc_altivec_vperm;
17466 PermCntlTy = MVT::v16i8;
17467 PermTy = MVT::v4i32;
17486 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
17490 BaseLoadOps, LDTy, BaseMMO);
17499 int IncValue = IncOffset;
17516 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
17520 ExtraLoadOps, LDTy, ExtraMMO);
17531 if (isLittleEndian)
17533 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17536 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17539 Perm = Subtarget.hasAltivec()
17540 ? DAG.
getNode(ISD::BITCAST, dl, VT, Perm)
17554 bool isLittleEndian = Subtarget.isLittleEndian();
17555 unsigned IID =
N->getConstantOperandVal(0);
17556 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17557 : Intrinsic::ppc_altivec_lvsl);
17558 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17565 .zext(
Add.getScalarValueSizeInBits()))) {
17566 SDNode *BasePtr =
Add->getOperand(0).getNode();
17567 for (
SDNode *U : BasePtr->users()) {
17569 U->getConstantOperandVal(0) == IID) {
17580 SDNode *BasePtr =
Add->getOperand(0).getNode();
17581 for (
SDNode *U : BasePtr->users()) {
17584 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17590 V->getConstantOperandVal(0) == IID) {
17602 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17603 IID == Intrinsic::ppc_altivec_vmaxsh ||
17604 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17635 switch (
N->getConstantOperandVal(1)) {
17638 case Intrinsic::ppc_altivec_vsum4sbs:
17639 case Intrinsic::ppc_altivec_vsum4shs:
17640 case Intrinsic::ppc_altivec_vsum4ubs: {
17647 APInt APSplatBits, APSplatUndef;
17648 unsigned SplatBitSize;
17651 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17652 !Subtarget.isLittleEndian());
17654 if (BVNIsConstantSplat && APSplatBits == 0)
17659 case Intrinsic::ppc_vsx_lxvw4x:
17660 case Intrinsic::ppc_vsx_lxvd2x:
17663 if (Subtarget.needsSwapsForVSXMemOps())
17671 if (Subtarget.needsSwapsForVSXMemOps()) {
17672 switch (
N->getConstantOperandVal(1)) {
17675 case Intrinsic::ppc_vsx_stxvw4x:
17676 case Intrinsic::ppc_vsx_stxvd2x:
17685 bool Is64BitBswapOn64BitTgt =
17686 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17688 N->getOperand(0).hasOneUse();
17689 if (IsSingleUseNormalLd &&
17690 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17691 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17702 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17703 MVT::i64 : MVT::i32, MVT::Other),
17704 Ops, LD->getMemoryVT(), LD->getMemOperand());
17708 if (
N->getValueType(0) == MVT::i16)
17725 !IsSingleUseNormalLd)
17730 if (!LD->isSimple())
17732 SDValue BasePtr = LD->getBasePtr();
17734 LD->getPointerInfo(), LD->getAlign());
17739 LD->getMemOperand(), 4, 4);
17743 if (Subtarget.isLittleEndian())
17749 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
17758 if (!
N->getOperand(0).hasOneUse() &&
17759 !
N->getOperand(1).hasOneUse() &&
17760 !
N->getOperand(2).hasOneUse()) {
17763 SDNode *VCMPrecNode =
nullptr;
17765 SDNode *LHSN =
N->getOperand(0).getNode();
17767 if (
User->getOpcode() == PPCISD::VCMP_rec &&
17771 VCMPrecNode =
User;
17783 SDNode *FlagUser =
nullptr;
17785 FlagUser ==
nullptr; ++UI) {
17786 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
17799 return SDValue(VCMPrecNode, 0);
17810 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
17821 auto RHSAPInt = RHS->getAsAPIntVal();
17822 if (!RHSAPInt.isIntN(64))
17825 unsigned Val = RHSAPInt.getZExtValue();
17826 auto isImpossibleCompare = [&]() {
17829 if (Val != 0 && Val != 1) {
17831 return N->getOperand(0);
17833 return DAG.
getNode(ISD::BR, dl, MVT::Other,
17834 N->getOperand(0),
N->getOperand(4));
17839 unsigned StoreWidth = 0;
17842 if (
SDValue Impossible = isImpossibleCompare())
17854 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
17858 PPCISD::STORE_COND, dl,
17860 MemNode->getMemoryVT(), MemNode->getMemOperand());
17864 if (
N->getOperand(0) == LHS.getValue(1))
17875 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
17877 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
17883 assert(isDot &&
"Can't compare against a vector result!");
17885 if (
SDValue Impossible = isImpossibleCompare())
17888 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
17895 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
17900 switch (LHS.getConstantOperandVal(1)) {
17916 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
17919 N->getOperand(4), CompNode.
getValue(1));
17924 return DAGCombineBuildVector(
N, DCI);
17937 EVT VT =
N->getValueType(0);
17938 if (VT == MVT::i64 && !Subtarget.isPPC64())
17940 if ((VT != MVT::i32 && VT != MVT::i64) ||
17948 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
17968 const APInt &DemandedElts,
17970 unsigned Depth)
const {
17972 switch (
Op.getOpcode()) {
17974 case PPCISD::LBRX: {
17977 Known.
Zero = 0xFFFF0000;
17980 case PPCISD::ADDE: {
17981 if (
Op.getResNo() == 0) {
17986 Known.
Zero = ~1ULL;
17991 switch (
Op.getConstantOperandVal(0)) {
17993 case Intrinsic::ppc_altivec_vcmpbfp_p:
17994 case Intrinsic::ppc_altivec_vcmpeqfp_p:
17995 case Intrinsic::ppc_altivec_vcmpequb_p:
17996 case Intrinsic::ppc_altivec_vcmpequh_p:
17997 case Intrinsic::ppc_altivec_vcmpequw_p:
17998 case Intrinsic::ppc_altivec_vcmpequd_p:
17999 case Intrinsic::ppc_altivec_vcmpequq_p:
18000 case Intrinsic::ppc_altivec_vcmpgefp_p:
18001 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18002 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18003 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18004 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18005 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18006 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18007 case Intrinsic::ppc_altivec_vcmpgtub_p:
18008 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18009 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18010 case Intrinsic::ppc_altivec_vcmpgtud_p:
18011 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18018 switch (
Op.getConstantOperandVal(1)) {
18021 case Intrinsic::ppc_load2r:
18023 Known.
Zero = 0xFFFF0000;
18032 switch (Subtarget.getCPUDirective()) {
18054 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18063 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18065 LoopSize +=
TII->getInstSizeInBytes(J);
18070 if (LoopSize > 16 && LoopSize <= 32)
18084 if (Constraint.
size() == 1) {
18085 switch (Constraint[0]) {
18103 }
else if (Constraint ==
"wc") {
18105 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18106 Constraint ==
"wf" || Constraint ==
"ws" ||
18107 Constraint ==
"wi" || Constraint ==
"ww") {
18120 Value *CallOperandVal =
info.CallOperandVal;
18123 if (!CallOperandVal)
18130 else if ((
StringRef(constraint) ==
"wa" ||
18142 switch (*constraint) {
18172std::pair<unsigned, const TargetRegisterClass *>
18176 if (Constraint.
size() == 1) {
18178 switch (Constraint[0]) {
18180 if (VT == MVT::i64 && Subtarget.isPPC64())
18181 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18182 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18184 if (VT == MVT::i64 && Subtarget.isPPC64())
18185 return std::make_pair(0U, &PPC::G8RCRegClass);
18186 return std::make_pair(0U, &PPC::GPRCRegClass);
18192 if (Subtarget.hasSPE()) {
18193 if (VT == MVT::f32 || VT == MVT::i32)
18194 return std::make_pair(0U, &PPC::GPRCRegClass);
18195 if (VT == MVT::f64 || VT == MVT::i64)
18196 return std::make_pair(0U, &PPC::SPERCRegClass);
18198 if (VT == MVT::f32 || VT == MVT::i32)
18199 return std::make_pair(0U, &PPC::F4RCRegClass);
18200 if (VT == MVT::f64 || VT == MVT::i64)
18201 return std::make_pair(0U, &PPC::F8RCRegClass);
18205 if (Subtarget.hasAltivec() && VT.
isVector())
18206 return std::make_pair(0U, &PPC::VRRCRegClass);
18207 else if (Subtarget.hasVSX())
18209 return std::make_pair(0U, &PPC::VFRCRegClass);
18212 return std::make_pair(0U, &PPC::CRRCRegClass);
18214 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18216 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18217 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18218 Constraint ==
"wf" || Constraint ==
"wi") &&
18219 Subtarget.hasVSX()) {
18223 return std::make_pair(0U, &PPC::VSRCRegClass);
18224 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18225 return std::make_pair(0U, &PPC::VSSRCRegClass);
18226 return std::make_pair(0U, &PPC::VSFRCRegClass);
18227 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18228 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18229 return std::make_pair(0U, &PPC::VSSRCRegClass);
18231 return std::make_pair(0U, &PPC::VSFRCRegClass);
18232 }
else if (Constraint ==
"lr") {
18233 if (VT == MVT::i64)
18234 return std::make_pair(0U, &PPC::LR8RCRegClass);
18236 return std::make_pair(0U, &PPC::LRRCRegClass);
18241 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18245 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18246 int VSNum = atoi(Constraint.
data() + 3);
18247 assert(VSNum >= 0 && VSNum <= 63 &&
18248 "Attempted to access a vsr out of range");
18250 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18251 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18256 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18257 int RegNum = atoi(Constraint.
data() + 2);
18258 if (RegNum > 31 || RegNum < 0)
18260 if (VT == MVT::f32 || VT == MVT::i32)
18261 return Subtarget.hasSPE()
18262 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18263 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18264 if (VT == MVT::f64 || VT == MVT::i64)
18265 return Subtarget.hasSPE()
18266 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18267 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18271 std::pair<unsigned, const TargetRegisterClass *> R =
18280 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18281 PPC::GPRCRegClass.contains(R.first))
18282 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18283 PPC::sub_32, &PPC::G8RCRegClass),
18284 &PPC::G8RCRegClass);
18287 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18288 R.first = PPC::CR0;
18289 R.second = &PPC::CRRCRegClass;
18293 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18294 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18295 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18296 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18297 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18298 "default AIX AltiVec ABI and cannot be used\n";
18308 std::vector<SDValue> &
Ops,
18313 if (Constraint.
size() > 1)
18316 char Letter = Constraint[0];
18331 EVT TCVT = MVT::i64;
18372 if (Result.getNode()) {
18373 Ops.push_back(Result);
18384 if (
I.getNumOperands() <= 1)
18388 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18389 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18390 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18393 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18409 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18421 switch (AM.
Scale) {
18449 unsigned Depth =
Op.getConstantOperandVal(0);
18473 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18481 unsigned Depth =
Op.getConstantOperandVal(0);
18488 bool isPPC64 = PtrVT == MVT::i64;
18494 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18496 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18502 FrameAddr, MachinePointerInfo());
18506#define GET_REGISTER_MATCHER
18507#include "PPCGenAsmMatcher.inc"
18511 bool IsPPC64 = Subtarget.isPPC64();
18523 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18529 Reg = Reg.id() - PPC::R0 + PPC::X0;
18536 if (Subtarget.is32BitELFABI())
18541 if (Subtarget.isAIXABI())
18555 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18571 case Intrinsic::ppc_atomicrmw_xchg_i128:
18572 case Intrinsic::ppc_atomicrmw_add_i128:
18573 case Intrinsic::ppc_atomicrmw_sub_i128:
18574 case Intrinsic::ppc_atomicrmw_nand_i128:
18575 case Intrinsic::ppc_atomicrmw_and_i128:
18576 case Intrinsic::ppc_atomicrmw_or_i128:
18577 case Intrinsic::ppc_atomicrmw_xor_i128:
18578 case Intrinsic::ppc_cmpxchg_i128:
18580 Info.memVT = MVT::i128;
18581 Info.ptrVal =
I.getArgOperand(0);
18583 Info.align =
Align(16);
18587 case Intrinsic::ppc_atomic_load_i128:
18589 Info.memVT = MVT::i128;
18590 Info.ptrVal =
I.getArgOperand(0);
18592 Info.align =
Align(16);
18595 case Intrinsic::ppc_atomic_store_i128:
18597 Info.memVT = MVT::i128;
18598 Info.ptrVal =
I.getArgOperand(2);
18600 Info.align =
Align(16);
18603 case Intrinsic::ppc_altivec_lvx:
18604 case Intrinsic::ppc_altivec_lvxl:
18605 case Intrinsic::ppc_altivec_lvebx:
18606 case Intrinsic::ppc_altivec_lvehx:
18607 case Intrinsic::ppc_altivec_lvewx:
18608 case Intrinsic::ppc_vsx_lxvd2x:
18609 case Intrinsic::ppc_vsx_lxvw4x:
18610 case Intrinsic::ppc_vsx_lxvd2x_be:
18611 case Intrinsic::ppc_vsx_lxvw4x_be:
18612 case Intrinsic::ppc_vsx_lxvl:
18613 case Intrinsic::ppc_vsx_lxvll: {
18616 case Intrinsic::ppc_altivec_lvebx:
18619 case Intrinsic::ppc_altivec_lvehx:
18622 case Intrinsic::ppc_altivec_lvewx:
18625 case Intrinsic::ppc_vsx_lxvd2x:
18626 case Intrinsic::ppc_vsx_lxvd2x_be:
18636 Info.ptrVal =
I.getArgOperand(0);
18639 Info.align =
Align(1);
18643 case Intrinsic::ppc_altivec_stvx:
18644 case Intrinsic::ppc_altivec_stvxl:
18645 case Intrinsic::ppc_altivec_stvebx:
18646 case Intrinsic::ppc_altivec_stvehx:
18647 case Intrinsic::ppc_altivec_stvewx:
18648 case Intrinsic::ppc_vsx_stxvd2x:
18649 case Intrinsic::ppc_vsx_stxvw4x:
18650 case Intrinsic::ppc_vsx_stxvd2x_be:
18651 case Intrinsic::ppc_vsx_stxvw4x_be:
18652 case Intrinsic::ppc_vsx_stxvl:
18653 case Intrinsic::ppc_vsx_stxvll: {
18656 case Intrinsic::ppc_altivec_stvebx:
18659 case Intrinsic::ppc_altivec_stvehx:
18662 case Intrinsic::ppc_altivec_stvewx:
18665 case Intrinsic::ppc_vsx_stxvd2x:
18666 case Intrinsic::ppc_vsx_stxvd2x_be:
18676 Info.ptrVal =
I.getArgOperand(1);
18679 Info.align =
Align(1);
18683 case Intrinsic::ppc_stdcx:
18684 case Intrinsic::ppc_stwcx:
18685 case Intrinsic::ppc_sthcx:
18686 case Intrinsic::ppc_stbcx: {
18688 auto Alignment =
Align(8);
18690 case Intrinsic::ppc_stdcx:
18693 case Intrinsic::ppc_stwcx:
18695 Alignment =
Align(4);
18697 case Intrinsic::ppc_sthcx:
18699 Alignment =
Align(2);
18701 case Intrinsic::ppc_stbcx:
18703 Alignment =
Align(1);
18708 Info.ptrVal =
I.getArgOperand(0);
18710 Info.align = Alignment;
18725 const AttributeList &FuncAttributes)
const {
18729 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
18730 if (
Op.isMemset() && Subtarget.hasVSX()) {
18735 if (TailSize > 2 && TailSize <= 4) {
18740 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
18745 if (Subtarget.isPPC64()) {
18756 assert(Ty->isIntegerTy());
18758 unsigned BitSize = Ty->getPrimitiveSizeInBits();
18759 return !(BitSize == 0 || BitSize > 64);
18767 return NumBits1 == 64 && NumBits2 == 32;
18775 return NumBits1 == 64 && NumBits2 == 32;
18782 EVT MemVT = LD->getMemoryVT();
18783 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
18784 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
18800 "invalid fpext types");
18802 if (DestVT == MVT::f128)
18817 unsigned *
Fast)
const {
18831 !Subtarget.allowsUnalignedFPAccess())
18835 if (Subtarget.hasVSX()) {
18836 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
18837 VT != MVT::v4f32 && VT != MVT::v4i32)
18844 if (VT == MVT::ppcf128)
18859 if (!ConstNode->getAPIntValue().isSignedIntN(64))
18867 int64_t Imm = ConstNode->getSExtValue();
18888 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
18890 switch (Ty->getScalarType()->getTypeID()) {
18895 return Subtarget.hasP9Vector();
18903 if (!
I->hasOneUse())
18907 assert(
User &&
"A single use instruction with no uses.");
18909 switch (
I->getOpcode()) {
18910 case Instruction::FMul: {
18912 if (
User->getOpcode() != Instruction::FSub &&
18913 User->getOpcode() != Instruction::FAdd)
18920 bool AllowContract =
I->getFastMathFlags().allowContract() &&
18921 User->getFastMathFlags().allowContract();
18927 case Instruction::Load: {
18940 if (
User->getOpcode() != Instruction::Store)
18960 static const MCPhysReg ScratchRegs[] = {
18961 PPC::X12, PPC::LR8, PPC::CTR8, 0
18964 return ScratchRegs;
18968 const Constant *PersonalityFn)
const {
18969 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
18973 const Constant *PersonalityFn)
const {
18974 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
18979 EVT VT ,
unsigned DefinedValues)
const {
18980 if (VT == MVT::v2i64)
18981 return Subtarget.hasDirectMove();
18983 if (Subtarget.hasVSX())
19010 return PPCISD::FNMSUB;
19011 case PPCISD::FNMSUB:
19017 bool LegalOps,
bool OptForSize,
19019 unsigned Depth)
const {
19023 unsigned Opc =
Op.getOpcode();
19024 EVT VT =
Op.getValueType();
19028 case PPCISD::FNMSUB:
19049 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
19053 N0Cost,
Depth + 1);
19057 N1Cost,
Depth + 1);
19059 if (NegN0 && N0Cost <= N1Cost) {
19060 Cost = std::min(N0Cost, N2Cost);
19062 }
else if (NegN1) {
19063 Cost = std::min(N1Cost, N2Cost);
19083 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19089 bool ForCodeSize)
const {
19090 if (!VT.
isSimple() || !Subtarget.hasVSX())
19100 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19105 APSInt IntResult(16,
false);
19110 if (IsExact && IntResult <= 15 && IntResult >= -16)
19112 return Imm.isZero();
19115 return Imm.isPosZero();
19127 unsigned Opcode =
N->getOpcode();
19147 if (Mask->getZExtValue() == OpSizeInBits - 1)
19154 DAGCombinerInfo &DCI)
const {
19155 EVT VT =
N->getValueType(0);
19158 unsigned Opc =
N->getOpcode();
19160 "Unexpected opcode.");
19167 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19171 uint64_t SplatBits = 0;
19172 bool AddSplatCase =
false;
19176 AddSplatCase =
true;
19180 if (!AddSplatCase) {
19184 unsigned SplatBitSize;
19186 APInt APSplatBits, APSplatUndef;
19188 bool BVNIsConstantSplat =
19190 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19191 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19202 if (SplatBits == (EltBits - 1)) {
19206 NewOpc = PPCISD::SHL;
19209 NewOpc = PPCISD::SRL;
19212 NewOpc = PPCISD::SRA;
19216 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19224 if (EltTy != MVT::i64 || SplatBits != 1)
19227 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19230SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19234 if (
N->getValueType(0).isVector())
19235 return combineVectorShift(
N, DCI);
19239 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19242 N->getValueType(0) != MVT::i64)
19257 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19263SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19267 if (
N->getValueType(0).isVector())
19268 return combineVectorShift(
N, DCI);
19273SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19277 if (
N->getValueType(0).isVector())
19278 return combineVectorShift(
N, DCI);
19289 if (!Subtarget.isPPC64())
19295 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19297 Op.getValueType() != MVT::i64)
19301 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19302 Cmp.getOperand(0).getValueType() != MVT::i64)
19306 int64_t NegConstant = 0 -
Constant->getSExtValue();
19315 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19316 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19319 if (LHSHasPattern && !RHSHasPattern)
19321 else if (!LHSHasPattern && !RHSHasPattern)
19325 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19328 SDValue Z = Cmp.getOperand(0);
19330 int64_t NegConstant = 0 -
Constant->getSExtValue();
19343 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19361 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19391 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19394 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19402 if (!GSDN || !ConstNode)
19430 EVT VT =
N->getValueType(0);
19431 if (!Subtarget.hasVSX())
19435 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19447 unsigned NumOfEles =
RHS.getNumOperands();
19448 for (
unsigned i = 0; i < NumOfEles; ++i) {
19450 if (!CN || CN->getSExtValue() != 1)
19465SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19487 DAGCombinerInfo &DCI)
const {
19489 if (Subtarget.useCRBits()) {
19491 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19492 return CRTruncValue;
19499 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19502 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19512 EltToExtract = EltToExtract ? 0 : 1;
19522 return DCI.DAG.getNode(
19524 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19529SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19530 SelectionDAG &DAG = DCI.DAG;
19533 if (!ConstOpOrElement)
19541 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19542 switch (this->Subtarget.getCPUDirective()) {
19565 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19569 EVT VT =
N->getValueType(0);
19574 APInt MulAmtAbs = MulAmt.
abs();
19576 if ((MulAmtAbs - 1).isPowerOf2()) {
19580 if (!IsProfitable(IsNeg,
true, VT))
19593 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19597 if (!IsProfitable(IsNeg,
false, VT))
19618 DAGCombinerInfo &DCI)
const {
19622 SDNodeFlags
Flags =
N->getFlags();
19623 EVT VT =
N->getValueType(0);
19624 SelectionDAG &DAG = DCI.DAG;
19626 unsigned Opc =
N->getOpcode();
19628 bool LegalOps = !DCI.isBeforeLegalizeOps();
19636 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
19652bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19654 if (!Subtarget.is64BitELFABI())
19664 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19669 if (!Callee ||
Callee->isVarArg())
19682bool PPCTargetLowering::
19683isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19688 if (CI->getBitWidth() > 64)
19690 int64_t ConstVal = CI->getZExtValue();
19692 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19701PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19707 if ((Flags & FlagSet) == FlagSet)
19710 if ((Flags & FlagSet) == FlagSet)
19713 if ((Flags & FlagSet) == FlagSet)
19716 if ((Flags & FlagSet) == FlagSet)
19737 if ((FrameIndexAlign % 4) != 0)
19738 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
19739 if ((FrameIndexAlign % 16) != 0)
19740 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
19744 if ((FrameIndexAlign % 4) == 0)
19746 if ((FrameIndexAlign % 16) == 0)
19759 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
19760 if ((Imm & 0x3) == 0)
19762 if ((Imm & 0xf) == 0)
19768 const APInt &ConstImm = CN->getAPIntValue();
19787 const APInt &ConstImm = CN->getAPIntValue();
19797 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
19808 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
19817unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
19822 if (!Subtarget.hasP9Vector())
19827 if (Subtarget.hasPrefixInstrs())
19830 if (Subtarget.hasSPE())
19839 unsigned ParentOp = Parent->
getOpcode();
19843 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
19844 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
19856 if (LSB->isIndexed())
19862 assert(MN &&
"Parent should be a MemSDNode!");
19867 "Not expecting scalar integers larger than 16 bytes!");
19870 else if (
Size == 32)
19877 else if (
Size == 256) {
19878 assert(Subtarget.pairedVectorMemops() &&
19879 "256-bit vectors are only available when paired vector memops is "
19887 else if (MemVT == MVT::f128 || MemVT.
isVector())
19918 FlagSet &= ~PPC::MOF_NoExt;
19923 bool IsNonP1034BitConst =
19927 IsNonP1034BitConst)
19940 int16_t ForceXFormImm = 0;
19943 Disp =
N.getOperand(0);
19944 Base =
N.getOperand(1);
19955 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
19956 Disp =
N.getOperand(0);
19957 Base =
N.getOperand(1);
19962 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
19971 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
19977 if (PartVT == MVT::f64 &&
19978 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
19980 Val = DAG.
getNode(ISD::BITCAST,
DL, MVT::f64, Val);
19987SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
19991 EVT RetVT =
Op.getValueType();
19998 EVT ArgVT =
N.getValueType();
20002 Entry.IsZExt = !Entry.IsSExt;
20003 Args.push_back(Entry);
20011 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20024SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20025 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20027 if (
Op.getValueType() == MVT::f32)
20028 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20030 if (
Op.getValueType() == MVT::f64)
20031 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20036bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20037 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20038 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20042bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20043 return Op.getNode()->getFlags().hasApproximateFuncs();
20046bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20050SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20051 const char *LibCallFloatName,
20052 const char *LibCallDoubleNameFinite,
20053 const char *LibCallFloatNameFinite,
20056 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20059 if (!isLowringToMASSFiniteSafe(
Op))
20060 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20063 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20064 LibCallDoubleNameFinite,
Op, DAG);
20068 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20069 "__xl_powf_finite",
Op, DAG);
20073 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20074 "__xl_sinf_finite",
Op, DAG);
20078 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20079 "__xl_cosf_finite",
Op, DAG);
20083 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20084 "__xl_logf_finite",
Op, DAG);
20088 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20089 "__xl_log10f_finite",
Op, DAG);
20093 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20094 "__xl_expf_finite",
Op, DAG);
20119 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20130 assert(Subtarget.isUsingPCRelativeCalls() &&
20131 "Must be using PC-Relative calls when a valid PC-Relative node is "
20161 Disp =
N.getOperand(1).getOperand(0);
20166 Base =
N.getOperand(0);
20174 EVT CNType = CN->getValueType(0);
20175 uint64_t CNImm = CN->getZExtValue();
20186 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20188 int32_t Addr = (int32_t)CNImm;
20193 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20209 unsigned Opcode =
N.getOpcode();
20217 Base =
N.getOperand(0);
20236 Base = FI ?
N :
N.getOperand(1);
20237 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20248 bool IsVarArg)
const {
20258 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20294 return Intrinsic::ppc_atomicrmw_xchg_i128;
20296 return Intrinsic::ppc_atomicrmw_add_i128;
20298 return Intrinsic::ppc_atomicrmw_sub_i128;
20300 return Intrinsic::ppc_atomicrmw_and_i128;
20302 return Intrinsic::ppc_atomicrmw_or_i128;
20304 return Intrinsic::ppc_atomicrmw_xor_i128;
20306 return Intrinsic::ppc_atomicrmw_nand_i128;
20314 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20316 assert(ValTy->getPrimitiveSizeInBits() == 128);
20318 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20320 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20321 Value *LoHi = Builder.CreateIntrinsic(
20323 {AlignedAddr, IncrLo, IncrHi});
20324 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20325 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20326 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20327 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20328 return Builder.CreateOr(
20329 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20336 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20338 assert(ValTy->getPrimitiveSizeInBits() == 128);
20342 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20344 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20345 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20347 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20350 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20352 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20353 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20354 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20355 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20356 return Builder.CreateOr(
20357 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20361 return Subtarget.useCRBits();
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS)
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left, SelectionDAG &DAG)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool canConvertSETCCToXori(SDNode *N)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble()
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
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.
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 & 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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool getTgtMemIntrinsic(IntrinsicInfo &Info, 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...
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
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
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...
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...
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)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
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 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...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
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.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
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...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
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 getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
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 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 NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
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...
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ ADD
Simple integer binary arithmetic operators.
@ 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.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ SSUBO
Same for subtraction.
@ 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).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ 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.
@ 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) ...
@ 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.
@ 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.
@ 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.
@ 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.
@ 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 ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ 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)...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
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.
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.
@ Define
Register definition.
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 bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.