69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
149 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
153 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
154 "function to use initial-exec"));
159 "Number of shuffles lowered to a VPERM or XXPERM");
160STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
167 unsigned OpIdx,
bool IsByte,
185 initializeAddrModeMap();
188 bool isPPC64 = Subtarget.isPPC64();
190 const MVT RegVT = Subtarget.getScalarIntVT();
198 if (!Subtarget.hasEFPU2())
215 if (!Subtarget.hasP10Vector()) {
244 if (Subtarget.isISA3_0()) {
277 if (!Subtarget.hasSPE()) {
284 if (Subtarget.useCRBits()) {
287 if (isPPC64 || Subtarget.hasFPCVT()) {
353 if (Subtarget.isISA3_0()) {
388 if (!Subtarget.hasSPE()) {
393 if (Subtarget.hasVSX()) {
398 if (Subtarget.hasFSQRT()) {
403 if (Subtarget.hasFPRND()) {
444 if (Subtarget.hasSPE()) {
454 if (Subtarget.hasSPE())
458 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
461 if (!Subtarget.hasFSQRT() &&
462 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
465 if (Subtarget.hasFCPSGN()) {
473 if (Subtarget.hasFPRND()) {
487 if (Subtarget.isISA3_1()) {
493 ((Subtarget.hasP8Vector()) && isPPC64) ?
Custom
498 if (Subtarget.isISA3_0()) {
518 if (!Subtarget.useCRBits()) {
531 if (!Subtarget.useCRBits())
534 if (Subtarget.hasFPU()) {
545 if (!Subtarget.useCRBits())
550 if (Subtarget.hasSPE()) {
574 if (Subtarget.hasDirectMove() && isPPC64) {
634 if (Subtarget.is64BitELFABI()) {
645 }
else if (Subtarget.is32BitELFABI()) {
653 if (Subtarget.is32BitELFABI())
669 if (Subtarget.isISA3_0() && isPPC64) {
697 if (Subtarget.hasSPE()) {
719 if (Subtarget.has64BitSupport()) {
734 if (Subtarget.hasLFIWAX() || isPPC64) {
740 if (Subtarget.hasSPE()) {
750 if (Subtarget.hasFPCVT()) {
751 if (Subtarget.has64BitSupport()) {
772 if (Subtarget.use64BitRegs()) {
790 if (Subtarget.has64BitSupport()) {
797 if (Subtarget.hasVSX()) {
810 if (Subtarget.hasAltivec()) {
811 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
828 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
841 if (Subtarget.hasVSX()) {
850 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
860 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
934 if (!Subtarget.hasP8Vector()) {
976 if (Subtarget.hasAltivec())
977 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
980 if (Subtarget.hasP8Altivec())
991 if (Subtarget.hasVSX()) {
997 if (Subtarget.hasP8Altivec())
1002 if (Subtarget.isISA3_1()) {
1048 if (Subtarget.hasVSX()) {
1051 if (Subtarget.hasP8Vector()) {
1055 if (Subtarget.hasDirectMove() && isPPC64) {
1104 if (Subtarget.hasP8Vector())
1113 if (Subtarget.hasP8Altivec()) {
1140 if (Subtarget.isISA3_1())
1243 if (Subtarget.hasP8Altivec()) {
1248 if (Subtarget.hasP9Vector()) {
1253 if (Subtarget.useCRBits()) {
1313 }
else if (Subtarget.hasVSX()) {
1338 for (
MVT VT : {MVT::f32, MVT::f64}) {
1357 if (Subtarget.hasP9Altivec()) {
1358 if (Subtarget.isISA3_1()) {
1381 if (Subtarget.hasP10Vector()) {
1386 if (Subtarget.pairedVectorMemops()) {
1391 if (Subtarget.hasMMA()) {
1392 if (Subtarget.isISAFuture()) {
1408 if (Subtarget.has64BitSupport())
1411 if (Subtarget.isISA3_1())
1429 if (Subtarget.hasAltivec()) {
1447 if (Subtarget.hasFPCVT())
1450 if (Subtarget.useCRBits())
1459 if (Subtarget.useCRBits()) {
1463 if (Subtarget.hasP8Vector())
1468 if (Subtarget.useCRBits()) {
1484 auto CPUDirective = Subtarget.getCPUDirective();
1485 switch (CPUDirective) {
1508 if (Subtarget.enableMachineScheduler())
1582void PPCTargetLowering::initializeAddrModeMap() {
1633 if (MaxAlign == MaxMaxAlign)
1636 if (MaxMaxAlign >= 32 &&
1637 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1638 MaxAlign =
Align(32);
1639 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1641 MaxAlign =
Align(16);
1645 if (EltAlign > MaxAlign)
1646 MaxAlign = EltAlign;
1648 for (
auto *EltTy : STy->elements()) {
1651 if (EltAlign > MaxAlign)
1652 MaxAlign = EltAlign;
1653 if (MaxAlign == MaxMaxAlign)
1666 if (Subtarget.hasAltivec())
1672 return Subtarget.useSoftFloat();
1676 return Subtarget.hasSPE();
1684 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1685 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1689 if (VTy->getScalarType()->isIntegerTy()) {
1691 if (ElemSizeInBits == 32) {
1692 Index = Subtarget.isLittleEndian() ? 2 : 1;
1695 if (ElemSizeInBits == 64) {
1696 Index = Subtarget.isLittleEndian() ? 1 : 0;
1707 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1724 return CFP->getValueAPF().isZero();
1729 return CFP->getValueAPF().isZero();
1737 return Op < 0 ||
Op == Val;
1749 if (ShuffleKind == 0) {
1752 for (
unsigned i = 0; i != 16; ++i)
1755 }
else if (ShuffleKind == 2) {
1758 for (
unsigned i = 0; i != 16; ++i)
1761 }
else if (ShuffleKind == 1) {
1762 unsigned j = IsLE ? 0 : 1;
1763 for (
unsigned i = 0; i != 8; ++i)
1780 if (ShuffleKind == 0) {
1783 for (
unsigned i = 0; i != 16; i += 2)
1787 }
else if (ShuffleKind == 2) {
1790 for (
unsigned i = 0; i != 16; i += 2)
1794 }
else if (ShuffleKind == 1) {
1795 unsigned j = IsLE ? 0 : 2;
1796 for (
unsigned i = 0; i != 8; i += 2)
1817 if (!Subtarget.hasP8Vector())
1821 if (ShuffleKind == 0) {
1824 for (
unsigned i = 0; i != 16; i += 4)
1830 }
else if (ShuffleKind == 2) {
1833 for (
unsigned i = 0; i != 16; i += 4)
1839 }
else if (ShuffleKind == 1) {
1840 unsigned j = IsLE ? 0 : 4;
1841 for (
unsigned i = 0; i != 8; i += 4)
1858 unsigned LHSStart,
unsigned RHSStart) {
1859 if (
N->getValueType(0) != MVT::v16i8)
1861 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1862 "Unsupported merge size!");
1864 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1865 for (
unsigned j = 0; j != UnitSize; ++j) {
1867 LHSStart+j+i*UnitSize) ||
1869 RHSStart+j+i*UnitSize))
1884 if (ShuffleKind == 1)
1886 else if (ShuffleKind == 2)
1891 if (ShuffleKind == 1)
1893 else if (ShuffleKind == 0)
1909 if (ShuffleKind == 1)
1911 else if (ShuffleKind == 2)
1916 if (ShuffleKind == 1)
1918 else if (ShuffleKind == 0)
1968 unsigned RHSStartValue) {
1969 if (
N->getValueType(0) != MVT::v16i8)
1972 for (
unsigned i = 0; i < 2; ++i)
1973 for (
unsigned j = 0; j < 4; ++j)
1975 i*RHSStartValue+j+IndexOffset) ||
1977 i*RHSStartValue+j+IndexOffset+8))
1999 unsigned indexOffset = CheckEven ? 4 : 0;
2000 if (ShuffleKind == 1)
2002 else if (ShuffleKind == 2)
2008 unsigned indexOffset = CheckEven ? 0 : 4;
2009 if (ShuffleKind == 1)
2011 else if (ShuffleKind == 0)
2027 if (
N->getValueType(0) != MVT::v16i8)
2034 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2037 if (i == 16)
return -1;
2042 if (ShiftAmt < i)
return -1;
2047 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2049 for (++i; i != 16; ++i)
2052 }
else if (ShuffleKind == 1) {
2054 for (++i; i != 16; ++i)
2061 ShiftAmt = 16 - ShiftAmt;
2070 EVT VT =
N->getValueType(0);
2071 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2072 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2075 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2079 if (
N->getMaskElt(0) % EltSize != 0)
2084 unsigned ElementBase =
N->getMaskElt(0);
2087 if (ElementBase >= 16)
2092 for (
unsigned i = 1; i != EltSize; ++i)
2093 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2096 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2098 if (
N->getMaskElt(i) < 0) {
2099 for (
unsigned j = 1; j != EltSize; ++j)
2100 if (
N->getMaskElt(i + j) >= 0)
2103 for (
unsigned j = 0; j != EltSize; ++j)
2104 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2121 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2122 "Unexpected element width.");
2123 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2125 unsigned NumOfElem = 16 / Width;
2126 unsigned MaskVal[16];
2127 for (
unsigned i = 0; i < NumOfElem; ++i) {
2128 MaskVal[0] =
N->getMaskElt(i * Width);
2129 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2131 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2135 for (
unsigned int j = 1; j < Width; ++j) {
2136 MaskVal[j] =
N->getMaskElt(i * Width + j);
2137 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2147 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2152 unsigned M0 =
N->getMaskElt(0) / 4;
2153 unsigned M1 =
N->getMaskElt(4) / 4;
2154 unsigned M2 =
N->getMaskElt(8) / 4;
2155 unsigned M3 =
N->getMaskElt(12) / 4;
2156 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2157 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2162 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2163 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2164 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2165 InsertAtByte = IsLE ? 12 : 0;
2170 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2171 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2172 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2173 InsertAtByte = IsLE ? 8 : 4;
2178 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2179 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2180 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2181 InsertAtByte = IsLE ? 4 : 8;
2186 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2187 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2188 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2189 InsertAtByte = IsLE ? 0 : 12;
2196 if (
N->getOperand(1).isUndef()) {
2199 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2200 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2201 InsertAtByte = IsLE ? 12 : 0;
2204 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2205 InsertAtByte = IsLE ? 8 : 4;
2208 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2209 InsertAtByte = IsLE ? 4 : 8;
2212 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2213 InsertAtByte = IsLE ? 0 : 12;
2222 bool &Swap,
bool IsLE) {
2223 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2229 unsigned M0 =
N->getMaskElt(0) / 4;
2230 unsigned M1 =
N->getMaskElt(4) / 4;
2231 unsigned M2 =
N->getMaskElt(8) / 4;
2232 unsigned M3 =
N->getMaskElt(12) / 4;
2236 if (
N->getOperand(1).isUndef()) {
2237 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2238 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2241 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2247 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2251 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2256 ShiftElts = (8 -
M0) % 8;
2257 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2262 ShiftElts = (4 -
M0) % 4;
2267 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2272 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2284 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2289 for (
int i = 0; i < 16; i += Width)
2290 if (
N->getMaskElt(i) != i + Width - 1)
2321 bool &Swap,
bool IsLE) {
2322 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2328 unsigned M0 =
N->getMaskElt(0) / 8;
2329 unsigned M1 =
N->getMaskElt(8) / 8;
2330 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2334 if (
N->getOperand(1).isUndef()) {
2335 if ((
M0 |
M1) < 2) {
2336 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2344 if (
M0 > 1 &&
M1 < 2) {
2354 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2359 }
else if (
M0 > 1 &&
M1 < 2) {
2367 DM = (
M0 << 1) + (
M1 & 1);
2382 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2387 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2403 unsigned EltSize = 16/
N->getNumOperands();
2404 if (EltSize < ByteSize) {
2405 unsigned Multiple = ByteSize/EltSize;
2407 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2410 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2411 if (
N->getOperand(i).isUndef())
continue;
2415 if (!UniquedVals[i&(Multiple-1)].
getNode())
2416 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2417 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2427 bool LeadingZero =
true;
2428 bool LeadingOnes =
true;
2429 for (
unsigned i = 0; i != Multiple-1; ++i) {
2430 if (!UniquedVals[i].
getNode())
continue;
2437 if (!UniquedVals[Multiple-1].
getNode())
2444 if (!UniquedVals[Multiple-1].
getNode())
2455 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2456 if (
N->getOperand(i).isUndef())
continue;
2458 OpVal =
N->getOperand(i);
2459 else if (OpVal !=
N->getOperand(i))
2465 unsigned ValSizeInBytes = EltSize;
2468 Value = CN->getZExtValue();
2470 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2477 if (ValSizeInBytes < ByteSize)
return SDValue();
2488 if (MaskVal == 0)
return SDValue();
2508 Imm = (int16_t)
N->getAsZExtVal();
2509 if (
N->getValueType(0) == MVT::i32)
2510 return Imm == (int32_t)
N->getAsZExtVal();
2512 return Imm == (int64_t)
N->getAsZExtVal();
2530 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2538 for (
SDNode *U :
N->users()) {
2540 if (Memop->getMemoryVT() == MVT::f64) {
2541 Base =
N.getOperand(0);
2542 Index =
N.getOperand(1);
2585 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2587 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2590 Base =
N.getOperand(0);
2591 Index =
N.getOperand(1);
2593 }
else if (
N.getOpcode() ==
ISD::OR) {
2595 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2607 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2608 Base =
N.getOperand(0);
2609 Index =
N.getOperand(1);
2679 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2685 Base =
N.getOperand(0);
2688 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2690 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2691 "Cannot handle constant offsets yet!");
2692 Disp =
N.getOperand(1).getOperand(0);
2697 Base =
N.getOperand(0);
2700 }
else if (
N.getOpcode() ==
ISD::OR) {
2703 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2717 Base =
N.getOperand(0);
2730 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2733 CN->getValueType(0));
2738 if ((CN->getValueType(0) == MVT::i32 ||
2739 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2740 (!EncodingAlignment ||
2741 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2742 int Addr = (int)CN->getZExtValue();
2749 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2770 if (
N.getValueType() != MVT::i64)
2783 Base =
N.getOperand(0);
2799 Base =
N.getOperand(0);
2832 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2833 Base =
N.getOperand(0);
2834 Index =
N.getOperand(1);
2856 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2877 EVT MemVT = LD->getMemoryVT();
2884 if (!ST.hasP8Vector())
2889 if (!ST.hasP9Vector())
2901 if (
Use.getResNo() == 0 &&
2903 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2923 Ptr = LD->getBasePtr();
2924 VT = LD->getMemoryVT();
2925 Alignment = LD->getAlign();
2927 Ptr = ST->getBasePtr();
2928 VT = ST->getMemoryVT();
2929 Alignment = ST->getAlign();
2968 if (VT != MVT::i64) {
2973 if (Alignment <
Align(4))
2983 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3000 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3042 EVT VT = Subtarget.getScalarIntVT();
3044 : Subtarget.isAIXABI()
3049 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3056 EVT PtrVT =
Op.getValueType();
3062 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3063 if (Subtarget.isUsingPCRelativeCalls()) {
3068 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3072 return getTOCEntry(DAG, SDLoc(CP), GA);
3075 unsigned MOHiFlag, MOLoFlag;
3079 if (IsPIC && Subtarget.isSVR4ABI()) {
3082 return getTOCEntry(DAG, SDLoc(CP), GA);
3105 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3112 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3129 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3142 EVT PtrVT =
Op.getValueType();
3160 return getTOCEntry(DAG,
SDLoc(JT), GA);
3163 unsigned MOHiFlag, MOLoFlag;
3167 if (IsPIC && Subtarget.isSVR4ABI()) {
3170 return getTOCEntry(DAG, SDLoc(GA), GA);
3180 EVT PtrVT =
Op.getValueType();
3185 if (Subtarget.isUsingPCRelativeCalls()) {
3196 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3199 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3208 unsigned MOHiFlag, MOLoFlag;
3218 if (Subtarget.isAIXABI())
3219 return LowerGlobalTLSAddressAIX(
Op, DAG);
3221 return LowerGlobalTLSAddressLinux(
Op, DAG);
3243 if (
I.getOpcode() == Instruction::Call)
3245 if (
Function *CF = CI->getCalledFunction())
3246 if (CF->isDeclaration() &&
3247 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3255 unsigned TLSGVCnt = TLSGV.
size();
3265 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3278 const GlobalValue *GV = GA->
getGlobal();
3280 bool Is64Bit = Subtarget.isPPC64();
3284 if (Subtarget.hasAIXShLibTLSModelOpt())
3294 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3295 bool HasAIXSmallTLSGlobalAttr =
false;
3298 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3302 if (GVar->hasAttribute(
"aix-small-tls"))
3303 HasAIXSmallTLSGlobalAttr =
true;
3322 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3323 IsTLSLocalExecModel) {
3328 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3338 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3343 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3345 "currently only supported on AIX (64-bit mode).");
3347 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3351 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3355 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3357 "currently only supported on AIX (64-bit mode).");
3365 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3368 GlobalVariable *TLSGV =
3372 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3375 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3377 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3386 if (HasAIXSmallLocalDynamicTLS) {
3391 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3395 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3408 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3409 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3410 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3425 const GlobalValue *GV = GA->
getGlobal();
3427 bool is64bit = Subtarget.isPPC64();
3435 if (Subtarget.isUsingPCRelativeCalls()) {
3440 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3441 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3452 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3456 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3463 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3465 MachinePointerInfo());
3472 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3474 if (!TM.isPositionIndependent())
3475 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3481 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3483 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGATLS);
3487 if (Subtarget.isUsingPCRelativeCalls()) {
3490 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3498 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3506 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3511 if (Subtarget.isUsingPCRelativeCalls()) {
3515 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3516 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3524 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3533 PtrVT, GOTPtr, TGA, TGA);
3535 PtrVT, TLSAddr, TGA);
3536 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3544 EVT PtrVT =
Op.getValueType();
3547 const GlobalValue *GV = GSDN->
getGlobal();
3551 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3552 if (Subtarget.isUsingPCRelativeCalls()) {
3559 MachinePointerInfo());
3564 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3569 return getTOCEntry(DAG,
DL, GA);
3572 unsigned MOHiFlag, MOLoFlag;
3576 if (IsPIC && Subtarget.isSVR4ABI()) {
3580 return getTOCEntry(DAG,
DL, GA);
3592 bool IsStrict =
Op->isStrictFPOpcode();
3598 EVT LHSVT =
LHS.getValueType();
3602 if (LHSVT == MVT::f128) {
3603 assert(!Subtarget.hasP9Vector() &&
3604 "SETCC for f128 is already legal under Power9!");
3615 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3617 if (
Op.getValueType() == MVT::v2i64) {
3620 if (
LHS.getValueType() == MVT::v2i64) {
3628 int ShuffV[] = {1, 0, 3, 2};
3633 dl, MVT::v4i32, Shuff, SetCC32));
3650 if (
C->isAllOnes() ||
C->isZero())
3660 EVT VT =
Op.getValueType();
3668 SDNode *
Node =
Op.getNode();
3669 EVT VT =
Node->getValueType(0);
3676 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3680 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3683 if (VT == MVT::i64) {
3702 FprPtr, MachinePointerInfo(SV), MVT::i8);
3713 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3714 InChain = OverflowArea.
getValue(1);
3717 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3747 MachinePointerInfo(SV), MVT::i8);
3760 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3761 MachinePointerInfo(), MVT::i32);
3763 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3767 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3773 false,
true,
nullptr, std::nullopt,
3774 MachinePointerInfo(), MachinePointerInfo());
3779 return Op.getOperand(0);
3784 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3788 "Expecting Inline ASM node.");
3798 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3803 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3804 unsigned NumVals =
Flags.getNumOperandRegisters();
3807 switch (
Flags.getKind()) {
3818 for (; NumVals; --NumVals, ++i) {
3820 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3843 if (Subtarget.isAIXABI()) {
3847 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3848 MaybeAlign PointerAlign(PointerSize);
3849 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3852 : MachineMemOperand::MONone;
3859 const Value *TrampolineAddr =
3869 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3870 PointerAlign, MMOFlags);
3872 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3873 MachinePointerInfo(TrampolineAddr, 0));
3877 SDValue TOCFromDescriptorPtr =
3879 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3880 MachinePointerInfo(Func, TOCPointerOffset),
3881 PointerAlign, MMOFlags);
3882 SDValue TrampolineTOCPointer =
3886 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3887 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3893 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3894 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3901 bool isPPC64 = (PtrVT == MVT::i64);
3905 Args.emplace_back(Trmp, IntPtrTy);
3908 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3910 Args.emplace_back(FPtr, IntPtrTy);
3911 Args.emplace_back(Nest, IntPtrTy);
3914 TargetLowering::CallLoweringInfo CLI(DAG);
3915 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3919 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3920 return CallResult.second;
3925 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3930 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
3935 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
3936 MachinePointerInfo(SV));
3970 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
3973 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
3976 uint64_t FPROffset = 1;
3984 MachinePointerInfo(SV), MVT::i8);
3985 uint64_t nextOffset = FPROffset;
3992 MachinePointerInfo(SV, nextOffset), MVT::i8);
3993 nextOffset += StackOffset;
3994 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
3997 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
3998 MachinePointerInfo(SV, nextOffset));
3999 nextOffset += FrameOffset;
4000 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4003 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4004 MachinePointerInfo(SV, nextOffset));
4009static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4010 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4011 PPC::F11, PPC::F12, PPC::F13};
4016 unsigned PtrByteSize) {
4018 if (Flags.isByVal())
4019 ArgSize = Flags.getByValSize();
4023 if (!Flags.isInConsecutiveRegs())
4024 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4033 unsigned PtrByteSize) {
4034 Align Alignment(PtrByteSize);
4037 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4038 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4039 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4040 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4041 Alignment =
Align(16);
4044 if (Flags.isByVal()) {
4045 auto BVAlign = Flags.getNonZeroByValAlign();
4046 if (BVAlign > PtrByteSize) {
4047 if (BVAlign.value() % PtrByteSize != 0)
4049 "ByVal alignment is not a multiple of the pointer size");
4051 Alignment = BVAlign;
4056 if (Flags.isInConsecutiveRegs()) {
4060 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4074 unsigned PtrByteSize,
unsigned LinkageSize,
4075 unsigned ParamAreaSize,
unsigned &ArgOffset,
4076 unsigned &AvailableFPRs,
4077 unsigned &AvailableVRs) {
4078 bool UseMemory =
false;
4083 ArgOffset =
alignTo(ArgOffset, Alignment);
4086 if (ArgOffset >= LinkageSize + ParamAreaSize)
4091 if (Flags.isInConsecutiveRegsLast())
4092 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4095 if (ArgOffset > LinkageSize + ParamAreaSize)
4100 if (!Flags.isByVal()) {
4101 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4102 if (AvailableFPRs > 0) {
4106 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4107 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4108 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4109 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4110 if (AvailableVRs > 0) {
4122 unsigned NumBytes) {
4126SDValue PPCTargetLowering::LowerFormalArguments(
4130 if (Subtarget.isAIXABI())
4131 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4133 if (Subtarget.is64BitELFABI())
4134 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4136 assert(Subtarget.is32BitELFABI());
4137 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4141SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4177 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4183 const Align PtrAlign(4);
4191 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4192 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4195 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4196 CCValAssign &VA = ArgLocs[i];
4200 const TargetRegisterClass *RC;
4208 RC = &PPC::GPRCRegClass;
4211 if (Subtarget.hasP8Vector())
4212 RC = &PPC::VSSRCRegClass;
4213 else if (Subtarget.hasSPE())
4214 RC = &PPC::GPRCRegClass;
4216 RC = &PPC::F4RCRegClass;
4219 if (Subtarget.hasVSX())
4220 RC = &PPC::VSFRCRegClass;
4221 else if (Subtarget.hasSPE())
4223 RC = &PPC::GPRCRegClass;
4225 RC = &PPC::F8RCRegClass;
4230 RC = &PPC::VRRCRegClass;
4233 RC = &PPC::VRRCRegClass;
4237 RC = &PPC::VRRCRegClass;
4244 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4245 assert(i + 1 < e &&
"No second half of double precision argument");
4250 if (!Subtarget.isLittleEndian())
4252 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4257 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4258 if (ValVT == MVT::i1)
4273 ArgOffset += ArgSize - ObjSize;
4291 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4296 unsigned MinReservedArea = CCByValInfo.getStackSize();
4297 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4313 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4314 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4316 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4319 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4322 unsigned NumFPArgRegs = std::size(FPArgRegs);
4331 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4332 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4335 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4348 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4363 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4367 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4380 if (!MemOps.
empty())
4391 const SDLoc &dl)
const {
4395 else if (
Flags.isZExt())
4402SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4408 bool isELFv2ABI = Subtarget.isELFv2ABI();
4409 bool isLittleEndian = Subtarget.isLittleEndian();
4412 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4415 "fastcc not supported on varargs functions");
4421 unsigned PtrByteSize = 8;
4422 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4425 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4426 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4429 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4430 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4433 const unsigned Num_GPR_Regs = std::size(GPR);
4435 const unsigned Num_VR_Regs = std::size(VR);
4443 bool HasParameterArea = !isELFv2ABI || isVarArg;
4444 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4445 unsigned NumBytes = LinkageSize;
4446 unsigned AvailableFPRs = Num_FPR_Regs;
4447 unsigned AvailableVRs = Num_VR_Regs;
4448 for (
const ISD::InputArg &In : Ins) {
4449 if (
In.Flags.isNest())
4453 LinkageSize, ParamAreaSize, NumBytes,
4454 AvailableFPRs, AvailableVRs))
4455 HasParameterArea =
true;
4462 unsigned ArgOffset = LinkageSize;
4463 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4466 unsigned CurArgIdx = 0;
4467 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4469 bool needsLoad =
false;
4470 EVT ObjectVT = Ins[ArgNo].VT;
4471 EVT OrigVT = Ins[ArgNo].ArgVT;
4473 unsigned ArgSize = ObjSize;
4474 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4475 if (Ins[ArgNo].isOrigArg()) {
4476 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4477 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4482 unsigned CurArgOffset;
4484 auto ComputeArgOffset = [&]() {
4488 ArgOffset =
alignTo(ArgOffset, Alignment);
4489 CurArgOffset = ArgOffset;
4496 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4497 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4502 if (
Flags.isByVal()) {
4503 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4509 ObjSize =
Flags.getByValSize();
4510 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4532 if (HasParameterArea ||
4533 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4540 if (ObjSize < PtrByteSize) {
4544 if (!isLittleEndian) {
4550 if (GPR_idx != Num_GPR_Regs) {
4557 MachinePointerInfo(&*FuncArg), ObjType);
4562 ArgOffset += PtrByteSize;
4571 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4572 if (GPR_idx == Num_GPR_Regs)
4583 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4587 MachinePointerInfo(&*FuncArg, j), ObjType);
4591 ArgOffset += ArgSize;
4600 if (
Flags.isNest()) {
4605 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4606 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4614 if (GPR_idx != Num_GPR_Regs) {
4619 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4622 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4628 ArgSize = PtrByteSize;
4639 if (FPR_idx != Num_FPR_Regs) {
4642 if (ObjectVT == MVT::f32)
4644 Subtarget.hasP8Vector()
4645 ? &PPC::VSSRCRegClass
4646 : &PPC::F4RCRegClass);
4649 ? &PPC::VSFRCRegClass
4650 : &PPC::F8RCRegClass);
4665 if (ObjectVT == MVT::f32) {
4666 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4684 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4685 ArgOffset += ArgSize;
4686 if (
Flags.isInConsecutiveRegsLast())
4687 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4701 if (VR_idx != Num_VR_Regs) {
4718 if (ObjSize < ArgSize && !isLittleEndian)
4719 CurArgOffset += ArgSize - ObjSize;
4722 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4729 unsigned MinReservedArea;
4730 if (HasParameterArea)
4731 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4733 MinReservedArea = LinkageSize;
4750 int Depth = ArgOffset;
4759 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4760 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4772 if (!MemOps.
empty())
4781 unsigned ParamSize) {
4783 if (!isTailCall)
return 0;
4787 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4789 if (SPDiff < FI->getTailCallSPDelta())
4805 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4864 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4867 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4879 const unsigned PtrByteSize = 8;
4883 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4884 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4887 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4888 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4891 const unsigned NumGPRs = std::size(GPR);
4892 const unsigned NumFPRs = 13;
4893 const unsigned NumVRs = std::size(VR);
4894 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4896 unsigned NumBytes = LinkageSize;
4897 unsigned AvailableFPRs = NumFPRs;
4898 unsigned AvailableVRs = NumVRs;
4901 if (Param.Flags.isNest())
continue;
4904 LinkageSize, ParamAreaSize, NumBytes,
4905 AvailableFPRs, AvailableVRs))
4916 auto CalleeArgEnd = CB.
arg_end();
4919 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4920 const Value* CalleeArg = *CalleeArgIter;
4921 const Value* CallerArg = &(*CallerArgIter);
4922 if (CalleeArg == CallerArg)
4948 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
4958bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
4963 bool isCalleeExternalSymbol)
const {
4966 if (
DisableSCO && !TailCallOpt)
return false;
4969 if (isVarArg)
return false;
4976 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5012 if (!Subtarget.isUsingPCRelativeCalls() &&
5017 if (!Subtarget.isUsingPCRelativeCalls() &&
5045bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5058 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5079 if (!
C)
return nullptr;
5081 int Addr =
C->getZExtValue();
5082 if ((Addr & 3) != 0 ||
5088 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5095struct TailCallArgumentInfo {
5100 TailCallArgumentInfo() =
default;
5110 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5111 SDValue Arg = TailCallArgs[i].Arg;
5112 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5113 int FI = TailCallArgs[i].FrameIdx;
5116 Chain, dl, Arg, FIN,
5125 int SPDiff,
const SDLoc &dl) {
5131 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5132 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5134 NewRetAddrLoc,
true);
5137 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5147 int SPDiff,
unsigned ArgOffset,
5149 int Offset = ArgOffset + SPDiff;
5152 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5154 TailCallArgumentInfo Info;
5156 Info.FrameIdxOp = FIN;
5164SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5169 LROpOut = getReturnAddrFrameIndex(DAG);
5170 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5171 MachinePointerInfo());
5188 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5196 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5220 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5230 if (!MemOpChains2.
empty())
5254SDValue PPCTargetLowering::LowerCallResult(
5262 CCRetInfo.AnalyzeCallResult(
5268 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5269 CCValAssign &VA = RVLocs[i];
5274 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5284 if (!Subtarget.isLittleEndian())
5286 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5352 bool IsStrictFPCall =
false) {
5354 return PPCISD::TC_RETURN;
5356 unsigned RetOpc = 0;
5367 if (Subtarget.usePointerGlueHelper())
5368 RetOpc = PPCISD::BL_LOAD_TOC;
5374 RetOpc = PPCISD::CALL_NOTOC;
5389 RetOpc = PPCISD::CALL;
5390 if (IsStrictFPCall) {
5394 case PPCISD::BCTRL_LOAD_TOC:
5395 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5398 RetOpc = PPCISD::BCTRL_RM;
5400 case PPCISD::BL_LOAD_TOC:
5401 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5403 case PPCISD::CALL_NOTOC:
5404 RetOpc = PPCISD::CALL_NOTOC_RM;
5407 RetOpc = PPCISD::CALL_RM;
5409 case PPCISD::CALL_NOP:
5410 RetOpc = PPCISD::CALL_NOP_RM;
5424 auto isLocalCallee = [&]() {
5440 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5456 return getAIXFuncEntryPointSymbolSDNode(GV);
5463 const char *SymName = S->getSymbol();
5470 return getAIXFuncEntryPointSymbolSDNode(
F);
5476 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5484 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5491 assert(Callee.getNode() &&
"What no callee?");
5497 "Expected a CALLSEQ_STARTSDNode.");
5514 SDValue MTCTROps[] = {Chain, Callee, Glue};
5515 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5516 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5556 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5575 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5576 Alignment, MMOFlags);
5583 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5590 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5602 "Nest parameter is not supported on AIX.");
5617 const SDLoc &dl,
bool hasNest,
5627 Chain = MoveToPhysicalReg.
getValue(0);
5628 Glue = MoveToPhysicalReg.
getValue(1);
5635 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5638 const bool IsPPC64 = Subtarget.isPPC64();
5643 Ops.push_back(Chain);
5647 Ops.push_back(Callee);
5648 else if (Subtarget.usePointerGlueHelper()) {
5649 Ops.push_back(Callee);
5672 Ops.push_back(AddTOC);
5683 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5692 for (
const auto &[
Reg,
N] : RegsToPass)
5710 assert(Mask &&
"Missing call preserved mask for calling convention");
5715 Ops.push_back(Glue);
5718SDValue PPCTargetLowering::FinishCall(
5725 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5726 Subtarget.isAIXABI())
5733 if (!CFlags.IsIndirect)
5735 else if (Subtarget.usesFunctionDescriptors()) {
5736 if (Subtarget.usePointerGlueHelper()) {
5738 CFlags.HasNest, Subtarget);
5744 dl, CFlags.HasNest, Subtarget);
5756 if (CFlags.IsTailCall) {
5764 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5765 "Expecting a global address, external symbol, absolute value, "
5766 "register or an indirect tail call when PC Relative calls are "
5769 assert(CallOpc == PPCISD::TC_RETURN &&
5770 "Unexpected call opcode for a tail call.");
5777 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5778 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5790 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5793 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5813 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5814 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5818bool PPCTargetLowering::isEligibleForTCO(
5823 bool isCalleeExternalSymbol)
const {
5827 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5828 return IsEligibleForTailCallOptimization_64SVR4(
5829 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5830 isCalleeExternalSymbol);
5832 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5860 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5875 "Callee should be an llvm::Function object.");
5878 <<
"\nTCO callee: ");
5885 "site marked musttail");
5892 Callee = LowerGlobalAddress(Callee, DAG);
5895 CallConv, isTailCall, isVarArg, isPatchPoint,
5898 Subtarget.is64BitELFABI() &&
5902 if (Subtarget.isAIXABI())
5903 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5906 assert(Subtarget.isSVR4ABI());
5907 if (Subtarget.isPPC64())
5908 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5910 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5914SDValue PPCTargetLowering::LowerCall_32SVR4(
5925 const bool IsVarArg = CFlags.IsVarArg;
5926 const bool IsTailCall = CFlags.IsTailCall;
5932 const Align PtrAlign(4);
5943 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
5951 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
5954 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
5961 unsigned NumArgs = Outs.
size();
5963 for (
unsigned i = 0; i != NumArgs; ++i) {
5964 MVT ArgVT = Outs[i].VT;
5965 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
5970 Outs[i].OrigTy, CCInfo);
5973 ArgFlags, Outs[i].OrigTy, CCInfo);
5978 errs() <<
"Call operand #" << i <<
" has unhandled type "
5991 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
5994 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6001 unsigned NumBytes = CCByValInfo.getStackSize();
6015 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6026 bool seenFloatArg =
false;
6031 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6033 ++i, ++RealArgIdx) {
6034 CCValAssign &VA = ArgLocs[i];
6035 SDValue Arg = OutVals[RealArgIdx];
6036 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6038 if (
Flags.isByVal()) {
6043 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6044 CCValAssign &ByValVA = ByValArgLocs[
j++];
6066 Chain = CallSeqStart = NewCallSeqStart;
6085 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6086 bool IsLE = Subtarget.isLittleEndian();
6087 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6090 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6092 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6107 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6116 if (!MemOpChains.
empty())
6122 for (
const auto &[
Reg,
N] : RegsToPass) {
6130 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6133 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6143 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6144 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6149SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6161 return NewCallSeqStart;
6164SDValue PPCTargetLowering::LowerCall_64SVR4(
6171 bool isELFv2ABI = Subtarget.isELFv2ABI();
6172 bool isLittleEndian = Subtarget.isLittleEndian();
6174 bool IsSibCall =
false;
6178 unsigned PtrByteSize = 8;
6191 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6193 assert(!(IsFastCall && CFlags.IsVarArg) &&
6194 "fastcc not supported on varargs functions");
6200 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6201 unsigned NumBytes = LinkageSize;
6202 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6205 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6206 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6209 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6210 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6213 const unsigned NumGPRs = std::size(GPR);
6215 const unsigned NumVRs = std::size(VR);
6221 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6222 if (!HasParameterArea) {
6223 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6224 unsigned AvailableFPRs = NumFPRs;
6225 unsigned AvailableVRs = NumVRs;
6226 unsigned NumBytesTmp = NumBytes;
6227 for (
unsigned i = 0; i !=
NumOps; ++i) {
6228 if (Outs[i].
Flags.isNest())
continue;
6230 PtrByteSize, LinkageSize, ParamAreaSize,
6231 NumBytesTmp, AvailableFPRs, AvailableVRs))
6232 HasParameterArea =
true;
6238 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6243 HasParameterArea =
false;
6246 for (
unsigned i = 0; i !=
NumOps; ++i) {
6247 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6248 EVT ArgVT = Outs[i].VT;
6249 EVT OrigVT = Outs[i].ArgVT;
6255 if (
Flags.isByVal()) {
6256 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6257 if (NumGPRsUsed > NumGPRs)
6258 HasParameterArea =
true;
6265 if (++NumGPRsUsed <= NumGPRs)
6275 if (++NumVRsUsed <= NumVRs)
6279 if (++NumVRsUsed <= NumVRs)
6284 if (++NumFPRsUsed <= NumFPRs)
6288 HasParameterArea =
true;
6295 NumBytes =
alignTo(NumBytes, Alignement);
6298 if (
Flags.isInConsecutiveRegsLast())
6299 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6302 unsigned NumBytesActuallyUsed = NumBytes;
6312 if (HasParameterArea)
6313 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6315 NumBytes = LinkageSize;
6330 if (CFlags.IsTailCall)
6342 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6353 unsigned ArgOffset = LinkageSize;
6359 for (
unsigned i = 0; i !=
NumOps; ++i) {
6361 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6362 EVT ArgVT = Outs[i].VT;
6363 EVT OrigVT = Outs[i].ArgVT;
6372 auto ComputePtrOff = [&]() {
6376 ArgOffset =
alignTo(ArgOffset, Alignment);
6387 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6388 GPR_idx = std::min(GPR_idx, NumGPRs);
6395 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6401 if (
Flags.isByVal()) {
6419 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6420 if (GPR_idx != NumGPRs) {
6422 MachinePointerInfo(), VT);
6424 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6426 ArgOffset += PtrByteSize;
6431 if (GPR_idx == NumGPRs &&
Size < 8) {
6433 if (!isLittleEndian) {
6438 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6441 ArgOffset += PtrByteSize;
6450 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6451 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6456 if (
Size < 8 && GPR_idx != NumGPRs) {
6466 if (!isLittleEndian) {
6470 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6476 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6478 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6481 ArgOffset += PtrByteSize;
6487 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6490 if (GPR_idx != NumGPRs) {
6491 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6494 MachinePointerInfo(), ObjType);
6497 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6498 ArgOffset += PtrByteSize;
6500 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6512 if (
Flags.isNest()) {
6514 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6521 if (GPR_idx != NumGPRs) {
6522 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6527 assert(HasParameterArea &&
6528 "Parameter area must exist to pass an argument in memory.");
6530 true, CFlags.IsTailCall,
false, MemOpChains,
6531 TailCallArguments, dl);
6533 ArgOffset += PtrByteSize;
6536 ArgOffset += PtrByteSize;
6549 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6550 bool NeededLoad =
false;
6553 if (FPR_idx != NumFPRs)
6554 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6557 if (!NeedGPROrStack)
6559 else if (GPR_idx != NumGPRs && !IsFastCall) {
6573 }
else if (!
Flags.isInConsecutiveRegs()) {
6579 }
else if (ArgOffset % PtrByteSize != 0) {
6583 if (!isLittleEndian)
6588 }
else if (
Flags.isInConsecutiveRegsLast()) {
6591 if (!isLittleEndian)
6601 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6609 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6614 assert(HasParameterArea &&
6615 "Parameter area must exist to pass an argument in memory.");
6617 true, CFlags.IsTailCall,
false, MemOpChains,
6618 TailCallArguments, dl);
6625 if (!IsFastCall || NeededLoad) {
6627 Flags.isInConsecutiveRegs()) ? 4 : 8;
6628 if (
Flags.isInConsecutiveRegsLast())
6629 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6649 if (CFlags.IsVarArg) {
6650 assert(HasParameterArea &&
6651 "Parameter area must exist if we have a varargs call.");
6655 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6657 if (VR_idx != NumVRs) {
6659 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6661 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6664 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6665 if (GPR_idx == NumGPRs)
6670 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6672 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6678 if (VR_idx != NumVRs) {
6679 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6684 assert(HasParameterArea &&
6685 "Parameter area must exist to pass an argument in memory.");
6687 true, CFlags.IsTailCall,
true, MemOpChains,
6688 TailCallArguments, dl);
6699 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6700 "mismatch in size of parameter area");
6701 (void)NumBytesActuallyUsed;
6703 if (!MemOpChains.
empty())
6709 if (CFlags.IsIndirect) {
6713 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6718 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6728 if (isELFv2ABI && !CFlags.IsPatchPoint)
6729 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6735 for (
const auto &[
Reg,
N] : RegsToPass) {
6740 if (CFlags.IsTailCall && !IsSibCall)
6744 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6745 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6752 "Required alignment greater than stack alignment.");
6772 return RequiredAlign <= 8;
6777 return RequiredAlign <= 4;
6785 State.getMachineFunction().getSubtarget());
6786 const bool IsPPC64 = Subtarget.isPPC64();
6787 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6788 const Align PtrAlign(PtrSize);
6789 const Align StackAlign(16);
6792 if (ValVT == MVT::f128)
6796 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6797 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6799 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6800 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6803 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6804 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6805 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6810 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6819 if (ByValAlign > StackAlign)
6821 "16 are not supported.");
6824 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6828 if (ByValSize == 0) {
6830 State.getStackSize(), RegVT, LocInfo));
6835 unsigned NextReg = State.getFirstUnallocated(GPRs);
6836 while (NextReg != GPRs.
size() &&
6841 State.AllocateStack(PtrSize, PtrAlign);
6842 assert(
Reg &&
"Alocating register unexpectedly failed.");
6844 NextReg = State.getFirstUnallocated(GPRs);
6847 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6848 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6868 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6872 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6891 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6897 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6899 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6900 if (State.isVarArg()) {
6932 const unsigned VecSize = 16;
6933 const Align VecAlign(VecSize);
6935 if (!State.isVarArg()) {
6938 if (
MCRegister VReg = State.AllocateReg(VR)) {
6945 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6950 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
6953 while (NextRegIndex != GPRs.
size() &&
6957 State.AllocateStack(PtrSize, PtrAlign);
6958 assert(
Reg &&
"Allocating register unexpectedly failed.");
6960 NextRegIndex = State.getFirstUnallocated(GPRs);
6968 if (
MCRegister VReg = State.AllocateReg(VR)) {
6971 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6972 State.AllocateReg(GPRs);
6973 State.AllocateStack(VecSize, VecAlign);
6977 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6983 if (NextRegIndex == GPRs.
size()) {
6984 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6992 if (GPRs[NextRegIndex] == PPC::R9) {
6993 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
6997 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
6998 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
6999 assert(FirstReg && SecondReg &&
7000 "Allocating R9 or R10 unexpectedly failed.");
7011 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7014 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7016 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7031 assert((IsPPC64 || SVT != MVT::i64) &&
7032 "i64 should have been split for 32-bit codegen.");
7040 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7042 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7044 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7052 return &PPC::VRRCRegClass;
7065 else if (Flags.isZExt())
7077 "Reg must be a valid argument register!");
7078 return LASize + 4 * (
Reg - PPC::R3);
7083 "Reg must be a valid argument register!");
7084 return LASize + 8 * (
Reg - PPC::X3);
7130SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7137 "Unexpected calling convention!");
7145 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7147 const bool IsPPC64 = Subtarget.isPPC64();
7148 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7154 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7155 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7159 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7160 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7161 uint64_t SaveStackPos = CCInfo.getStackSize();
7163 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7167 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7168 CCValAssign &VA = ArgLocs[
I++];
7173 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7174 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7186 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7188 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7194 MachinePointerInfo(),
Align(PtrByteSize));
7200 unsigned StoreSize =
7202 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7205 auto HandleMemLoc = [&]() {
7208 assert((ValSize <= LocSize) &&
7209 "Object size is larger than size of MemLoc");
7212 if (LocSize > ValSize)
7213 CurArgOffset += LocSize - ValSize;
7215 const bool IsImmutable =
7221 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7255 assert(isVarArg &&
"Only use custom memloc for vararg.");
7258 const unsigned OriginalValNo = VA.
getValNo();
7259 (void)OriginalValNo;
7261 auto HandleCustomVecRegLoc = [&]() {
7262 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7263 "Missing custom RegLoc.");
7266 "Unexpected Val type for custom RegLoc.");
7268 "ValNo mismatch between custom MemLoc and RegLoc.");
7272 Subtarget.hasVSX()));
7279 HandleCustomVecRegLoc();
7280 HandleCustomVecRegLoc();
7284 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7286 "Only 2 custom RegLocs expected for 64-bit codegen.");
7287 HandleCustomVecRegLoc();
7288 HandleCustomVecRegLoc();
7332 const unsigned Size =
7344 if (
Flags.isByVal()) {
7348 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7350 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7358 const TargetRegisterClass *RegClass =
7359 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7361 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7374 CopyFrom.
getValue(1), dl, CopyFrom,
7384 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7387 "RegLocs should be for ByVal argument.");
7389 const CCValAssign RL = ArgLocs[
I++];
7394 if (
Offset != StackSize) {
7396 "Expected MemLoc for remaining bytes.");
7397 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7411 Subtarget.hasVSX()));
7428 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7430 unsigned CallerReservedArea = std::max<unsigned>(
7431 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7437 CallerReservedArea =
7442 int VAListIndex = 0;
7446 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7447 unsigned FixedStackSize =
7448 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7464 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7465 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7467 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7468 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7469 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7475 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7477 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7480 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7481 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7484 MachinePointerInfo MPI =
7494 if (!MemOps.
empty())
7500SDValue PPCTargetLowering::LowerCall_AIX(
7513 "Unexpected calling convention!");
7515 if (CFlags.IsPatchPoint)
7518 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7522 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7529 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7530 const bool IsPPC64 = Subtarget.isPPC64();
7532 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7533 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7534 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7542 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7543 const unsigned NumBytes = std::max<unsigned>(
7544 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7560 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7561 const unsigned ValNo = ArgLocs[
I].getValNo();
7563 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7565 if (
Flags.isByVal()) {
7566 const unsigned ByValSize =
Flags.getByValSize();
7574 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7580 MachinePointerInfo(), VT);
7583 unsigned LoadOffset = 0;
7586 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7589 LoadOffset += PtrByteSize;
7590 const CCValAssign &ByValVA = ArgLocs[
I++];
7592 "Unexpected location for pass-by-value argument.");
7596 if (LoadOffset == ByValSize)
7600 assert(ArgLocs[
I].getValNo() == ValNo &&
7601 "Expected additional location for by-value argument.");
7603 if (ArgLocs[
I].isMemLoc()) {
7604 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7605 const CCValAssign &ByValVA = ArgLocs[
I++];
7606 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7609 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7615 CallSeqStart, MemcpyFlags, DAG, dl);
7624 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7625 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7626 "Unexpected register residue for by-value argument.");
7628 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7632 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7642 "Unexpected load emitted during handling of pass-by-value "
7650 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7655 const CCValAssign &ByValVA = ArgLocs[
I++];
7660 CCValAssign &VA = ArgLocs[
I++];
7685 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7691 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7693 const unsigned OriginalValNo = VA.
getValNo();
7695 unsigned LoadOffset = 0;
7696 auto HandleCustomVecRegLoc = [&]() {
7697 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7698 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7699 "Expected custom RegLoc.");
7700 CCValAssign RegVA = ArgLocs[
I++];
7702 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7708 LoadOffset += PtrByteSize;
7714 HandleCustomVecRegLoc();
7715 HandleCustomVecRegLoc();
7717 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7718 ArgLocs[
I].getValNo() == OriginalValNo) {
7720 "Only 2 custom RegLocs expected for 64-bit codegen.");
7721 HandleCustomVecRegLoc();
7722 HandleCustomVecRegLoc();
7733 DAG.
getStore(Chain, dl, Arg, PtrOff,
7735 Subtarget.getFrameLowering()->getStackAlign()));
7742 "Unexpected register handling for calling convention.");
7748 "Custom register handling only expected for VarArg.");
7753 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7757 else if (Arg.getValueType().getFixedSizeInBits() <
7765 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7766 "Unexpected custom register for argument!");
7767 CCValAssign &GPR1 = VA;
7776 CCValAssign &PeekArg = ArgLocs[
I];
7779 CCValAssign &GPR2 = ArgLocs[
I++];
7787 if (!MemOpChains.
empty())
7792 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7793 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7794 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7795 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7796 const MVT PtrVT = Subtarget.getScalarIntVT();
7797 const unsigned TOCSaveOffset =
7798 Subtarget.getFrameLowering()->getTOCSaveOffset();
7813 for (
auto Reg : RegsToPass) {
7818 const int SPDiff = 0;
7819 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7820 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7828 const Type *RetTy)
const {
7830 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7831 return CCInfo.CheckReturn(
7846 CCInfo.AnalyzeReturn(Outs,
7855 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7856 CCValAssign &VA = RVLocs[i];
7859 SDValue Arg = OutVals[RealResIdx];
7874 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7875 bool isLittleEndian = Subtarget.isLittleEndian();
7878 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7882 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7897 RetOps.push_back(Glue);
7899 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7903PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7908 EVT IntVT =
Op.getValueType();
7912 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7916 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7928 bool isPPC64 = Subtarget.isPPC64();
7929 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7938 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
7944 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
7949 bool isPPC64 = Subtarget.isPPC64();
7954 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7960 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
7970PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7972 bool isPPC64 = Subtarget.isPPC64();
7977 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
7983 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8006 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8008 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8010 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8011 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8018 bool isPPC64 = Subtarget.isPPC64();
8028 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8030 Op.getOperand(0),
Op.getOperand(1));
8036 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8037 Op.getOperand(0),
Op.getOperand(1));
8041 if (
Op.getValueType().isVector())
8042 return LowerVectorLoad(
Op, DAG);
8044 assert(
Op.getValueType() == MVT::i1 &&
8045 "Custom lowering only for i1 loads");
8054 MachineMemOperand *MMO =
LD->getMemOperand();
8058 BasePtr, MVT::i8, MMO);
8066 if (
Op.getOperand(1).getValueType().isVector())
8067 return LowerVectorStore(
Op, DAG);
8069 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8070 "Custom lowering only for i1 stores");
8080 MachineMemOperand *MMO =
ST->getMemOperand();
8089 assert(
Op.getValueType() == MVT::i1 &&
8090 "Custom lowering only for i1 results");
8118 EVT TrgVT =
Op.getValueType();
8142 if (SrcSize == 256) {
8153 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8159 SmallVector<int, 16> ShuffV;
8160 if (Subtarget.isLittleEndian())
8161 for (
unsigned i = 0; i < TrgNumElts; ++i)
8164 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8168 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8181 EVT ResVT =
Op.getValueType();
8182 EVT CmpVT =
Op.getOperand(0).getValueType();
8184 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8190 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8203 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8207 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8224 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8237 if (
LHS.getValueType() == MVT::f32)
8239 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8242 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8250 if (
LHS.getValueType() == MVT::f32)
8252 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8259 if (
LHS.getValueType() == MVT::f32)
8261 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8273 if (
Cmp.getValueType() == MVT::f32)
8275 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8278 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8283 if (
Cmp.getValueType() == MVT::f32)
8285 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8289 if (
Cmp.getValueType() == MVT::f32)
8291 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8295 if (
Cmp.getValueType() == MVT::f32)
8297 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8301 if (
Cmp.getValueType() == MVT::f32)
8303 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8312 case PPCISD::FCTIDZ:
8313 return PPCISD::STRICT_FCTIDZ;
8314 case PPCISD::FCTIWZ:
8315 return PPCISD::STRICT_FCTIWZ;
8316 case PPCISD::FCTIDUZ:
8317 return PPCISD::STRICT_FCTIDUZ;
8318 case PPCISD::FCTIWUZ:
8319 return PPCISD::STRICT_FCTIWUZ;
8321 return PPCISD::STRICT_FCFID;
8322 case PPCISD::FCFIDU:
8323 return PPCISD::STRICT_FCFIDU;
8324 case PPCISD::FCFIDS:
8325 return PPCISD::STRICT_FCFIDS;
8326 case PPCISD::FCFIDUS:
8327 return PPCISD::STRICT_FCFIDUS;
8334 bool IsStrict =
Op->isStrictFPOpcode();
8343 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8345 MVT DestTy =
Op.getSimpleValueType();
8346 assert(Src.getValueType().isFloatingPoint() &&
8347 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8348 DestTy == MVT::i64) &&
8349 "Invalid FP_TO_INT types");
8350 if (Src.getValueType() == MVT::f32) {
8354 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8359 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8365 Opc = IsSigned ? PPCISD::FCTIWZ
8366 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8369 assert((IsSigned || Subtarget.hasFPCVT()) &&
8370 "i64 FP_TO_UINT is supported only with FPCVT");
8371 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8373 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8385void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8387 const SDLoc &dl)
const {
8391 bool IsStrict =
Op->isStrictFPOpcode();
8394 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8395 (IsSigned || Subtarget.hasFPCVT());
8398 MachinePointerInfo MPI =
8406 Alignment =
Align(4);
8407 MachineMemOperand *MMO =
8413 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8417 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8418 !Subtarget.isLittleEndian()) {
8427 RLI.Alignment = Alignment;
8435 const SDLoc &dl)
const {
8438 if (
Op->isStrictFPOpcode())
8445 const SDLoc &dl)
const {
8446 bool IsStrict =
Op->isStrictFPOpcode();
8449 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8450 EVT SrcVT = Src.getValueType();
8451 EVT DstVT =
Op.getValueType();
8454 if (SrcVT == MVT::f128)
8455 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8459 if (SrcVT == MVT::ppcf128) {
8460 if (DstVT == MVT::i32) {
8465 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8476 {Op.getOperand(0), Lo, Hi}, Flags);
8479 {Res.getValue(1), Res}, Flags);
8485 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8509 {Chain, Src, FltOfs}, Flags);
8513 {Chain, Val}, Flags);
8516 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8534 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8535 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8538 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8540 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8541 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8552bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8557 if (
Op->isStrictFPOpcode())
8562 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8566 Op.getOperand(0).getValueType())) {
8568 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8573 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8574 LD->isNonTemporal())
8576 if (
LD->getMemoryVT() != MemVT)
8586 RLI.Ptr =
LD->getBasePtr();
8587 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8589 "Non-pre-inc AM on PPC?");
8594 RLI.Chain =
LD->getChain();
8595 RLI.MPI =
LD->getPointerInfo();
8596 RLI.IsDereferenceable =
LD->isDereferenceable();
8597 RLI.IsInvariant =
LD->isInvariant();
8598 RLI.Alignment =
LD->getAlign();
8599 RLI.AAInfo =
LD->getAAInfo();
8600 RLI.Ranges =
LD->getRanges();
8602 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8609bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8610 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8617 if (!Subtarget.hasP9Vector() &&
8621 for (SDUse &Use : Origin->
uses()) {
8624 if (
Use.getResNo() != 0)
8651 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8652 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8653 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8654 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8655 if (
Op->isStrictFPOpcode()) {
8657 Chain =
Op.getOperand(0);
8659 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8661 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8669 const SDLoc &dl)
const {
8670 assert((
Op.getValueType() == MVT::f32 ||
8671 Op.getValueType() == MVT::f64) &&
8672 "Invalid floating point type as target of conversion");
8673 assert(Subtarget.hasFPCVT() &&
8674 "Int to FP conversions with direct moves require FPCVT");
8675 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8676 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8679 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8698 for (
unsigned i = 1; i < NumConcat; ++i)
8705 const SDLoc &dl)
const {
8706 bool IsStrict =
Op->isStrictFPOpcode();
8707 unsigned Opc =
Op.getOpcode();
8708 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8711 "Unexpected conversion type");
8712 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8713 "Supports conversions to v2f64/v4f32 only.");
8717 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8720 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8725 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8727 SmallVector<int, 16> ShuffV;
8728 for (
unsigned i = 0; i < WideNumElts; ++i)
8731 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8732 int SaveElts = FourEltRes ? 4 : 2;
8733 if (Subtarget.isLittleEndian())
8734 for (
int i = 0; i < SaveElts; i++)
8735 ShuffV[i * Stride] = i;
8737 for (
int i = 1; i <= SaveElts; i++)
8738 ShuffV[i * Stride - 1] = i - 1;
8746 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8747 EVT ExtVT = Src.getValueType();
8748 if (Subtarget.hasP9Altivec())
8759 {Op.getOperand(0), Extend}, Flags);
8761 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8769 bool IsStrict =
Op->isStrictFPOpcode();
8770 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8775 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8777 EVT InVT = Src.getValueType();
8778 EVT OutVT =
Op.getValueType();
8781 return LowerINT_TO_FPVector(
Op, DAG, dl);
8784 if (
Op.getValueType() == MVT::f128)
8785 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8788 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8791 if (Src.getValueType() == MVT::i1) {
8803 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8804 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8805 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8807 assert((IsSigned || Subtarget.hasFPCVT()) &&
8808 "UINT_TO_FP is supported only with FPCVT");
8810 if (Src.getValueType() == MVT::i64) {
8825 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8826 !
Op->getFlags().hasApproximateFuncs()) {
8866 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8867 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8868 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8871 }
else if (Subtarget.hasLFIWAX() &&
8872 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8873 MachineMemOperand *MMO =
8875 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8879 Ops, MVT::i32, MMO);
8882 }
else if (Subtarget.hasFPCVT() &&
8883 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8884 MachineMemOperand *MMO =
8886 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8890 Ops, MVT::i32, MMO);
8893 }
else if (((Subtarget.hasLFIWAX() &&
8895 (Subtarget.hasFPCVT() &&
8910 "Expected an i32 store");
8916 RLI.Alignment =
Align(4);
8918 MachineMemOperand *MMO =
8920 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8923 PPCISD::LFIWZX : PPCISD::LFIWAX,
8924 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8925 Ops, MVT::i32, MMO);
8926 Chain =
Bits.getValue(1);
8934 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8938 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
8947 assert(Src.getValueType() == MVT::i32 &&
8948 "Unhandled INT_TO_FP type in custom expander!");
8958 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8961 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8971 "Expected an i32 store");
8977 RLI.Alignment =
Align(4);
8980 MachineMemOperand *MMO =
8982 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8988 if (ReusingLoad && RLI.ResChain) {
8992 assert(Subtarget.isPPC64() &&
8993 "i32->FP without LFIWAX supported only on PPC64");
9002 Chain, dl, Ext64, FIdx,
9008 MVT::f64, dl, Chain, FIdx,
9017 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9021 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9038 uint64_t
Mode = CVal->getZExtValue();
9039 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9040 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9041 if (Subtarget.isISA3_0())
9044 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9045 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9048 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9049 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9051 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9069 if (!Subtarget.isISA3_0()) {
9070 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9074 if (Subtarget.isPPC64()) {
9075 if (Subtarget.isISA3_0()) {
9080 PPC::RLDIMI, Dl, MVT::i64,
9085 NewFPSCR =
SDValue(InsertRN, 0);
9092 SDValue Addr = Subtarget.isLittleEndian()
9096 if (Subtarget.isISA3_0()) {
9097 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9099 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9101 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9104 PPC::RLWIMI, Dl, MVT::i32,
9105 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9106 DAG.getTargetConstant(30, Dl, MVT::i32),
9107 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9109 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9112 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9115 if (Subtarget.isISA3_0())
9121 PPC::MTFSF, Dl, MVT::Other,
9149 EVT VT =
Op.getValueType();
9154 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9165 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9169 "Stack slot adjustment is valid only on big endian subtargets!");
9172 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9199 EVT VT =
Op.getValueType();
9203 VT ==
Op.getOperand(1).getValueType() &&
9223 SDValue OutOps[] = { OutLo, OutHi };
9228 EVT VT =
Op.getValueType();
9232 VT ==
Op.getOperand(1).getValueType() &&
9252 SDValue OutOps[] = { OutLo, OutHi };
9258 EVT VT =
Op.getValueType();
9261 VT ==
Op.getOperand(1).getValueType() &&
9281 SDValue OutOps[] = { OutLo, OutHi };
9288 EVT VT =
Op.getValueType();
9295 EVT AmtVT =
Z.getValueType();
9305 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9306 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9318 static const MVT VTys[] = {
9319 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9322 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9325 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9330 EVT CanonicalVT = VTys[SplatSize-1];
9343 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9344 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9353 EVT DestVT = MVT::Other) {
9354 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9363 EVT DestVT = MVT::Other) {
9366 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9378 for (
unsigned i = 0; i != 16; ++i)
9399 EVT VecVT = V->getValueType(0);
9400 bool RightType = VecVT == MVT::v2f64 ||
9401 (HasP8Vector && VecVT == MVT::v4f32) ||
9402 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9406 bool IsSplat =
true;
9407 bool IsLoad =
false;
9413 if (V->isConstant())
9415 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9416 if (V->getOperand(i).isUndef())
9420 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9422 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9424 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9426 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9430 if (V->getOperand(i) != Op0 ||
9431 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9434 return !(IsSplat && IsLoad);
9444 (
Op.getValueType() != MVT::f128))
9449 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9452 if (!Subtarget.isLittleEndian())
9455 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9463 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9464 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9477 APFloat APFloatToConvert = ArgAPFloat;
9478 bool LosesInfo =
true;
9483 ArgAPFloat = APFloatToConvert;
9505 APFloat APFloatToConvert = ArgAPFloat;
9506 bool LosesInfo =
true;
9510 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9519 EVT Ty =
Op->getValueType(0);
9522 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9531 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9535 if (Ty == MVT::v2i64) {
9538 if (MemVT == MVT::i32) {
9540 Opcode = PPCISD::ZEXT_LD_SPLAT;
9542 Opcode = PPCISD::SEXT_LD_SPLAT;
9550 bool IsLittleEndian) {
9556 APInt ConstValue(VTSize, 0);
9560 unsigned BitPos = 0;
9568 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9569 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9573 for (
unsigned J = 0; J < 16; ++J) {
9575 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9577 if (ExtractValue == 0xFF)
9592 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9594 if (Subtarget.hasP10Vector()) {
9595 APInt BitMask(32, 0);
9601 BitMask != 0 && BitMask != 0xffff) {
9603 MachineSDNode *MSDNode =
9615 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9619 APInt APSplatBits, APSplatUndef;
9620 unsigned SplatBitSize;
9622 bool BVNIsConstantSplat =
9624 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9630 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9631 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9634 if ((
Op->getValueType(0) == MVT::v2f64) &&
9637 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9653 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9659 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9667 bool IsSplat64 =
false;
9668 uint64_t SplatBits = 0;
9669 int32_t SextVal = 0;
9670 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9672 if (SplatBitSize <= 32) {
9674 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9675 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9676 bool P9Vector = Subtarget.hasP9Vector();
9677 int32_t
Hi = P9Vector ? 127 : 15;
9678 int32_t
Lo = P9Vector ? -128 : -16;
9679 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9680 SextVal =
static_cast<int32_t
>(SplatBits);
9684 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9685 unsigned NewOpcode = PPCISD::LD_SPLAT;
9691 const SDValue *InputLoad = &
Op.getOperand(0);
9696 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9697 unsigned ElementSize =
9698 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9700 assert(((ElementSize == 2 * MemorySize)
9701 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9702 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9703 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9704 "Unmatched element size and opcode!\n");
9709 unsigned NumUsesOfInputLD = 128 / ElementSize;
9711 if (BVInOp.isUndef())
9726 if (NumUsesOfInputLD == 1 &&
9727 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9728 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9729 Subtarget.hasLFIWAX()))
9737 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9738 Subtarget.isISA3_1() && ElementSize <= 16)
9741 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9743 Subtarget.hasVSX()) {
9750 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9751 LD->getMemoryVT(),
LD->getMemOperand());
9763 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9765 Subtarget.hasP8Vector()))
9771 unsigned SplatSize = SplatBitSize / 8;
9776 if (SplatBits == 0) {
9778 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9790 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9792 Op.getValueType(), DAG, dl);
9794 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9799 if (Subtarget.hasP9Vector() && SplatSize == 1)
9805 if (SextVal >= -16 && SextVal <= 15) {
9808 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9815 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9821 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9827 switch (SplatSize) {
9831 IID = Intrinsic::ppc_altivec_vupklsb;
9835 IID = Intrinsic::ppc_altivec_vextsb2w;
9839 IID = Intrinsic::ppc_altivec_vextsb2d;
9846 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9855 if (SextVal >= -32 && SextVal <= 31) {
9860 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9861 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9864 if (VT ==
Op.getValueType())
9873 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9887 static const signed char SplatCsts[] = {
9888 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9889 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9892 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9895 int i = SplatCsts[idx];
9899 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9902 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9904 static const unsigned IIDs[] = {
9905 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9906 Intrinsic::ppc_altivec_vslw
9913 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9915 static const unsigned IIDs[] = {
9916 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9917 Intrinsic::ppc_altivec_vsrw
9924 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9925 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9927 static const unsigned IIDs[] = {
9928 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9929 Intrinsic::ppc_altivec_vrlw
9936 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9938 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
9942 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9944 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
9948 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9950 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
9963 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9964 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9965 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9981 if (LHSID == (1*9+2)*9+3)
return LHS;
9982 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9994 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9995 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9996 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9997 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10000 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10001 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10002 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10003 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10006 for (
unsigned i = 0; i != 16; ++i)
10007 ShufIdxs[i] = (i&3)+0;
10010 for (
unsigned i = 0; i != 16; ++i)
10011 ShufIdxs[i] = (i&3)+4;
10014 for (
unsigned i = 0; i != 16; ++i)
10015 ShufIdxs[i] = (i&3)+8;
10018 for (
unsigned i = 0; i != 16; ++i)
10019 ShufIdxs[i] = (i&3)+12;
10040 const unsigned BytesInVector = 16;
10041 bool IsLE = Subtarget.isLittleEndian();
10045 unsigned ShiftElts = 0, InsertAtByte = 0;
10049 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10050 0, 15, 14, 13, 12, 11, 10, 9};
10051 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10052 1, 2, 3, 4, 5, 6, 7, 8};
10054 ArrayRef<int>
Mask =
N->getMask();
10055 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10067 bool FoundCandidate =
false;
10071 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10074 for (
unsigned i = 0; i < BytesInVector; ++i) {
10075 unsigned CurrentElement =
Mask[i];
10078 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10081 bool OtherElementsInOrder =
true;
10084 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10091 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10092 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10093 OtherElementsInOrder =
false;
10100 if (OtherElementsInOrder) {
10107 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10108 : BigEndianShifts[CurrentElement & 0xF];
10109 Swap = CurrentElement < BytesInVector;
10111 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10112 FoundCandidate =
true;
10117 if (!FoundCandidate)
10127 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10129 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, Shl,
10132 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8, V1, V2,
10141 const unsigned NumHalfWords = 8;
10142 const unsigned BytesInVector = NumHalfWords * 2;
10147 bool IsLE = Subtarget.isLittleEndian();
10151 unsigned ShiftElts = 0, InsertAtByte = 0;
10155 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10156 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10159 uint32_t OriginalOrderLow = 0x1234567;
10160 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10163 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10164 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10181 bool FoundCandidate =
false;
10184 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10185 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10187 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10188 uint32_t TargetOrder = 0x0;
10195 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10196 TargetOrder = OriginalOrderLow;
10200 if (MaskOneElt == VINSERTHSrcElem &&
10201 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10202 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10203 FoundCandidate =
true;
10209 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10211 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10213 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10214 : BigEndianShifts[MaskOneElt & 0x7];
10215 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10216 Swap = MaskOneElt < NumHalfWords;
10217 FoundCandidate =
true;
10223 if (!FoundCandidate)
10235 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10238 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10243 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10258 auto ShuffleMask = SVN->
getMask();
10273 ShuffleMask = CommutedSV->
getMask();
10282 APInt APSplatValue, APSplatUndef;
10283 unsigned SplatBitSize;
10286 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10298 bool IsLE = Subtarget.isLittleEndian();
10299 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10300 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10301 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10303 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10304 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10305 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10313 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10314 SplatVal |= (SplatVal << SplatBitSize);
10317 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10328 assert(
Op.getValueType() == MVT::v1i128 &&
10329 "Only set v1i128 as custom, other type shouldn't reach here!");
10334 if (SHLAmt % 8 == 0) {
10335 std::array<int, 16>
Mask;
10336 std::iota(
Mask.begin(),
Mask.end(), 0);
10337 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10366 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10371 V1 =
Op.getOperand(0);
10372 V2 =
Op.getOperand(1);
10374 EVT VT =
Op.getValueType();
10375 bool isLittleEndian = Subtarget.isLittleEndian();
10377 unsigned ShiftElts, InsertAtByte;
10383 bool IsPermutedLoad =
false;
10385 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10395 if (IsPermutedLoad) {
10396 assert((isLittleEndian || IsFourByte) &&
10397 "Unexpected size for permuted load on big endian target");
10398 SplatIdx += IsFourByte ? 2 : 1;
10399 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10400 "Splat of a value outside of the loaded memory");
10405 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10408 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10410 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10414 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10427 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10430 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10439 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10442 if (Subtarget.hasP9Vector() &&
10452 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10454 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10458 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10463 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10465 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10466 return SplatInsertNode;
10469 if (Subtarget.hasP9Altivec()) {
10471 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10474 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10478 if (Subtarget.hasVSX() &&
10486 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10491 if (Subtarget.hasVSX() &&
10499 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10504 if (Subtarget.hasP9Vector()) {
10524 if (Subtarget.hasVSX()) {
10537 SDValue Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10545 if (V2.isUndef()) {
10558 (Subtarget.hasP8Altivec() && (
10569 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10579 (Subtarget.hasP8Altivec() && (
10587 ArrayRef<int> PermMask = SVOp->
getMask();
10590 unsigned PFIndexes[4];
10591 bool isFourElementShuffle =
true;
10592 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10594 unsigned EltNo = 8;
10595 for (
unsigned j = 0;
j != 4; ++
j) {
10596 if (PermMask[i * 4 + j] < 0)
10599 unsigned ByteSource = PermMask[i * 4 +
j];
10600 if ((ByteSource & 3) != j) {
10601 isFourElementShuffle =
false;
10606 EltNo = ByteSource / 4;
10607 }
else if (EltNo != ByteSource / 4) {
10608 isFourElementShuffle =
false;
10612 PFIndexes[i] = EltNo;
10620 if (isFourElementShuffle) {
10622 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10623 PFIndexes[2] * 9 + PFIndexes[3];
10626 unsigned Cost = (PFEntry >> 30);
10646 if (V2.isUndef()) V2 = V1;
10648 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10654 unsigned Opcode = PPCISD::VPERM;
10657 bool NeedSwap =
false;
10658 bool isLittleEndian = Subtarget.isLittleEndian();
10659 bool isPPC64 = Subtarget.isPPC64();
10661 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10663 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10664 "XXPERM instead\n");
10665 Opcode = PPCISD::XXPERM;
10673 NeedSwap = !NeedSwap;
10708 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10710 if (V1HasXXSWAPD) {
10713 else if (SrcElt < 16)
10716 if (V2HasXXSWAPD) {
10719 else if (SrcElt > 15)
10728 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10729 if (isLittleEndian)
10731 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10734 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10737 if (V1HasXXSWAPD) {
10741 if (V2HasXXSWAPD) {
10746 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10747 if (ValType != MVT::v2f64)
10753 ShufflesHandledWithVPERM++;
10757 if (Opcode == PPCISD::XXPERM) {
10758 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10760 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10763 dbgs() <<
"With the following permute control vector:\n";
10767 if (Opcode == PPCISD::XXPERM)
10768 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10772 if (isLittleEndian)
10778 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10790 switch (IntrinsicID) {
10794 case Intrinsic::ppc_altivec_vcmpbfp_p:
10798 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10802 case Intrinsic::ppc_altivec_vcmpequb_p:
10806 case Intrinsic::ppc_altivec_vcmpequh_p:
10810 case Intrinsic::ppc_altivec_vcmpequw_p:
10814 case Intrinsic::ppc_altivec_vcmpequd_p:
10815 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10821 case Intrinsic::ppc_altivec_vcmpneb_p:
10822 case Intrinsic::ppc_altivec_vcmpneh_p:
10823 case Intrinsic::ppc_altivec_vcmpnew_p:
10824 case Intrinsic::ppc_altivec_vcmpnezb_p:
10825 case Intrinsic::ppc_altivec_vcmpnezh_p:
10826 case Intrinsic::ppc_altivec_vcmpnezw_p:
10827 if (Subtarget.hasP9Altivec()) {
10828 switch (IntrinsicID) {
10831 case Intrinsic::ppc_altivec_vcmpneb_p:
10834 case Intrinsic::ppc_altivec_vcmpneh_p:
10837 case Intrinsic::ppc_altivec_vcmpnew_p:
10840 case Intrinsic::ppc_altivec_vcmpnezb_p:
10843 case Intrinsic::ppc_altivec_vcmpnezh_p:
10846 case Intrinsic::ppc_altivec_vcmpnezw_p:
10854 case Intrinsic::ppc_altivec_vcmpgefp_p:
10858 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10862 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10866 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10870 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10874 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10875 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10881 case Intrinsic::ppc_altivec_vcmpgtub_p:
10885 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10889 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10893 case Intrinsic::ppc_altivec_vcmpgtud_p:
10894 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10901 case Intrinsic::ppc_altivec_vcmpequq:
10902 case Intrinsic::ppc_altivec_vcmpgtsq:
10903 case Intrinsic::ppc_altivec_vcmpgtuq:
10904 if (!Subtarget.isISA3_1())
10906 switch (IntrinsicID) {
10909 case Intrinsic::ppc_altivec_vcmpequq:
10912 case Intrinsic::ppc_altivec_vcmpgtsq:
10915 case Intrinsic::ppc_altivec_vcmpgtuq:
10922 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10923 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10924 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10925 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10926 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10927 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10928 if (Subtarget.hasVSX()) {
10929 switch (IntrinsicID) {
10930 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10933 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10936 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10939 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10942 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10945 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10955 case Intrinsic::ppc_altivec_vcmpbfp:
10958 case Intrinsic::ppc_altivec_vcmpeqfp:
10961 case Intrinsic::ppc_altivec_vcmpequb:
10964 case Intrinsic::ppc_altivec_vcmpequh:
10967 case Intrinsic::ppc_altivec_vcmpequw:
10970 case Intrinsic::ppc_altivec_vcmpequd:
10971 if (Subtarget.hasP8Altivec())
10976 case Intrinsic::ppc_altivec_vcmpneb:
10977 case Intrinsic::ppc_altivec_vcmpneh:
10978 case Intrinsic::ppc_altivec_vcmpnew:
10979 case Intrinsic::ppc_altivec_vcmpnezb:
10980 case Intrinsic::ppc_altivec_vcmpnezh:
10981 case Intrinsic::ppc_altivec_vcmpnezw:
10982 if (Subtarget.hasP9Altivec())
10983 switch (IntrinsicID) {
10986 case Intrinsic::ppc_altivec_vcmpneb:
10989 case Intrinsic::ppc_altivec_vcmpneh:
10992 case Intrinsic::ppc_altivec_vcmpnew:
10995 case Intrinsic::ppc_altivec_vcmpnezb:
10998 case Intrinsic::ppc_altivec_vcmpnezh:
11001 case Intrinsic::ppc_altivec_vcmpnezw:
11008 case Intrinsic::ppc_altivec_vcmpgefp:
11011 case Intrinsic::ppc_altivec_vcmpgtfp:
11014 case Intrinsic::ppc_altivec_vcmpgtsb:
11017 case Intrinsic::ppc_altivec_vcmpgtsh:
11020 case Intrinsic::ppc_altivec_vcmpgtsw:
11023 case Intrinsic::ppc_altivec_vcmpgtsd:
11024 if (Subtarget.hasP8Altivec())
11029 case Intrinsic::ppc_altivec_vcmpgtub:
11032 case Intrinsic::ppc_altivec_vcmpgtuh:
11035 case Intrinsic::ppc_altivec_vcmpgtuw:
11038 case Intrinsic::ppc_altivec_vcmpgtud:
11039 if (Subtarget.hasP8Altivec())
11044 case Intrinsic::ppc_altivec_vcmpequq_p:
11045 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11046 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11047 if (!Subtarget.isISA3_1())
11049 switch (IntrinsicID) {
11052 case Intrinsic::ppc_altivec_vcmpequq_p:
11055 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11058 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11072 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11078 auto MapNodeWithSplatVector =
11079 [&](
unsigned Opcode,
11080 std::initializer_list<SDValue> ExtraOps = {}) ->
SDValue {
11085 Ops.append(ExtraOps.begin(), ExtraOps.end());
11086 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11089 switch (IntrinsicID) {
11090 case Intrinsic::thread_pointer:
11092 if (Subtarget.isPPC64())
11096 case Intrinsic::ppc_rldimi: {
11097 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11099 APInt
Mask =
Op.getConstantOperandAPInt(4);
11101 return Op.getOperand(2);
11102 if (
Mask.isAllOnes())
11104 uint64_t SH =
Op.getConstantOperandVal(3);
11105 unsigned MB = 0, ME = 0;
11109 if (ME < 63 - SH) {
11112 }
else if (ME > 63 - SH) {
11118 {Op.getOperand(2), Src,
11119 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11120 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11124 case Intrinsic::ppc_rlwimi: {
11125 APInt
Mask =
Op.getConstantOperandAPInt(4);
11127 return Op.getOperand(2);
11128 if (
Mask.isAllOnes())
11131 unsigned MB = 0, ME = 0;
11135 PPC::RLWIMI, dl, MVT::i32,
11136 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11137 DAG.getTargetConstant(MB, dl, MVT::i32),
11138 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11142 case Intrinsic::ppc_bcdshift:
11143 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11144 case Intrinsic::ppc_bcdshiftround:
11145 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11146 case Intrinsic::ppc_bcdtruncate:
11147 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11148 case Intrinsic::ppc_bcdunsignedtruncate:
11149 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11150 case Intrinsic::ppc_bcdunsignedshift:
11151 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11153 case Intrinsic::ppc_rlwnm: {
11154 if (
Op.getConstantOperandVal(3) == 0)
11156 unsigned MB = 0, ME = 0;
11161 {Op.getOperand(1), Op.getOperand(2),
11162 DAG.getTargetConstant(MB, dl, MVT::i32),
11163 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11167 case Intrinsic::ppc_mma_disassemble_acc: {
11168 if (Subtarget.isISAFuture()) {
11169 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11180 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11181 Subtarget.isLittleEndian() ? Value2 :
Value,
11182 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11186 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11187 Subtarget.isLittleEndian() ? Value2 :
Value,
11188 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11192 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11193 Subtarget.isLittleEndian() ?
Value : Value2,
11194 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11198 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11199 Subtarget.isLittleEndian() ?
Value : Value2,
11200 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11207 case Intrinsic::ppc_vsx_disassemble_pair: {
11210 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11212 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11215 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11217 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11218 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11226 case Intrinsic::ppc_build_dmr: {
11229 for (
int i = 1; i < 9; i += 2) {
11237 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11244 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11245 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11247 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11248 "Specify P of 0 or 1 for lower or upper 512 bytes");
11249 unsigned HiLo = Idx->getSExtValue();
11253 Opcode = PPC::DMXXEXTFDMR512;
11254 Subx = PPC::sub_wacc_lo;
11256 Opcode = PPC::DMXXEXTFDMR512_HI;
11257 Subx = PPC::sub_wacc_hi;
11260 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11264 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11268 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11269 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11271 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11272 "Specify a dmr row pair 0-3");
11273 unsigned IdxVal = Idx->getSExtValue();
11277 Subx = PPC::sub_dmrrowp0;
11280 Subx = PPC::sub_dmrrowp1;
11283 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11286 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11290 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11296 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11300 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11301 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11303 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11304 "Specify P of 0 or 1 for lower or upper 512 bytes");
11305 unsigned HiLo = Idx->getSExtValue();
11309 Opcode = PPCISD::INST512;
11310 Subx = PPC::sub_wacc_lo;
11312 Opcode = PPCISD::INST512HI;
11313 Subx = PPC::sub_wacc_hi;
11319 Op.getOperand(1), Wacc, SubReg),
11323 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11324 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11326 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11327 "Specify a dmr row pair 0-3");
11328 unsigned IdxVal = Idx->getSExtValue();
11332 Subx = PPC::sub_dmrrowp0;
11335 Subx = PPC::sub_dmrrowp1;
11338 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11341 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11347 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11349 Op.getOperand(1), DMRRowp, SubReg),
11353 case Intrinsic::ppc_mma_xxmfacc:
11354 case Intrinsic::ppc_mma_xxmtacc: {
11356 if (!Subtarget.isISAFuture())
11367 case Intrinsic::ppc_unpack_longdouble: {
11369 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11370 "Argument of long double unpack must be 0 or 1!");
11373 Idx->getValueType(0)));
11376 case Intrinsic::ppc_compare_exp_lt:
11377 case Intrinsic::ppc_compare_exp_gt:
11378 case Intrinsic::ppc_compare_exp_eq:
11379 case Intrinsic::ppc_compare_exp_uo: {
11381 switch (IntrinsicID) {
11382 case Intrinsic::ppc_compare_exp_lt:
11385 case Intrinsic::ppc_compare_exp_gt:
11388 case Intrinsic::ppc_compare_exp_eq:
11391 case Intrinsic::ppc_compare_exp_uo:
11397 PPC::SELECT_CC_I4, dl, MVT::i32,
11398 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11399 Op.getOperand(1), Op.getOperand(2)),
11401 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11402 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11405 case Intrinsic::ppc_test_data_class: {
11406 EVT OpVT =
Op.getOperand(1).getValueType();
11407 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11408 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11421 {Op.getOperand(2), Op.getOperand(1)}),
11423 if (Subtarget.isISA3_1()) {
11430 TestDataClass, SubRegIdx),
11433 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11439 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11440 DAG.getConstant(0, dl, MVT::i32),
11441 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11444 case Intrinsic::ppc_fnmsub: {
11445 EVT VT =
Op.getOperand(1).getValueType();
11446 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11451 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11452 Op.getOperand(2),
Op.getOperand(3));
11454 case Intrinsic::ppc_convert_f128_to_ppcf128:
11455 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11456 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11457 ? RTLIB::CONVERT_PPCF128_F128
11458 : RTLIB::CONVERT_F128_PPCF128;
11460 std::pair<SDValue, SDValue>
Result =
11461 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11465 case Intrinsic::ppc_maxfe:
11466 case Intrinsic::ppc_maxfl:
11467 case Intrinsic::ppc_maxfs:
11468 case Intrinsic::ppc_minfe:
11469 case Intrinsic::ppc_minfl:
11470 case Intrinsic::ppc_minfs: {
11471 EVT VT =
Op.getValueType();
11474 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11475 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11478 if (IntrinsicID == Intrinsic::ppc_minfe ||
11479 IntrinsicID == Intrinsic::ppc_minfl ||
11480 IntrinsicID == Intrinsic::ppc_minfs)
11501 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11502 Op.getOperand(1),
Op.getOperand(2),
11513 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11521 switch (
Op.getConstantOperandVal(1)) {
11526 Bitx = PPC::sub_eq;
11527 SetOp = PPCISD::SETBC;
11532 Bitx = PPC::sub_eq;
11533 SetOp = PPCISD::SETBCR;
11538 Bitx = PPC::sub_lt;
11539 SetOp = PPCISD::SETBC;
11544 Bitx = PPC::sub_lt;
11545 SetOp = PPCISD::SETBCR;
11550 if (Subtarget.isISA3_1()) {
11555 CR6Reg, SubRegIdx, GlueOp),
11557 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11585 switch (
Op.getConstantOperandVal(ArgStart)) {
11586 case Intrinsic::ppc_cfence: {
11587 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11588 SDValue Val =
Op.getOperand(ArgStart + 1);
11590 if (Ty == MVT::i128) {
11595 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11598 Opcode,
DL, MVT::Other,
11603 case Intrinsic::ppc_disassemble_dmr: {
11605 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11606 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11607 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11618 if (!Subtarget.isPPC64())
11621 if (Subtarget.hasP9Vector()) {
11628 int VectorIndex = 0;
11629 if (Subtarget.isLittleEndian())
11639 auto CreateRotateInsert =
11640 [&](
unsigned Opcode, MVT VT,
SDValue Dest,
SDValue Src,
unsigned RotAmt,
11641 unsigned MaskBegin,
11642 std::optional<unsigned> MaskEnd = std::nullopt) ->
SDValue {
11646 if (MaskEnd.has_value())
11658 CreateRotateInsert(PPC::RLWIMI, MVT::i32, Rot, Val32, 24, 0, 7);
11660 return CreateRotateInsert(PPC::RLWIMI, MVT::i32, Swap, Val32, 24, 16, 23);
11673 return CreateRotateInsert(PPC::RLDIMI, MVT::i64, HiSwap, LoSwap, 32, 0);
11681 "Expecting an atomic compare-and-swap here.");
11684 EVT MemVT = AtomicNode->getMemoryVT();
11702 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11703 Ops.push_back(AtomicNode->getOperand(i));
11705 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11706 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11708 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11715 EVT MemVT =
N->getMemoryVT();
11717 "Expect quadword atomic operations");
11719 unsigned Opc =
N->getOpcode();
11724 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11727 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11728 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11729 Ops.push_back(
N->getOperand(
I));
11731 Ops, MemVT,
N->getMemOperand());
11738 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11745 SDVTList Tys = DAG.
getVTList(MVT::Other);
11748 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11754 Ops.push_back(ValLo);
11755 Ops.push_back(ValHi);
11756 Ops.push_back(
N->getOperand(2));
11758 N->getMemOperand());
11770 enum DataClassMask {
11772 DC_NEG_INF = 1 << 4,
11773 DC_POS_INF = 1 << 5,
11774 DC_NEG_ZERO = 1 << 2,
11775 DC_POS_ZERO = 1 << 3,
11776 DC_NEG_SUBNORM = 1,
11777 DC_POS_SUBNORM = 1 << 1,
11780 EVT VT =
Op.getValueType();
11782 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11783 : VT == MVT::f64 ? PPC::XSTSTDCDP
11794 return DAG.
getNOT(Dl, Rev, MVT::i1);
11801 TestOp, Dl, MVT::i32,
11803 DC_NEG_ZERO | DC_POS_ZERO |
11804 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11810 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11816 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11821 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11834 bool IsQuiet = Mask &
fcQNan;
11840 if (VT == MVT::f128) {
11844 QuietMask = 0x8000;
11845 }
else if (VT == MVT::f64) {
11846 if (Subtarget.isPPC64()) {
11857 QuietMask = 0x80000;
11858 }
else if (VT == MVT::f32) {
11860 QuietMask = 0x400000;
11876 unsigned NativeMask = 0;
11878 NativeMask |= DC_NAN;
11880 NativeMask |= DC_NEG_INF;
11882 NativeMask |= DC_POS_INF;
11884 NativeMask |= DC_NEG_ZERO;
11886 NativeMask |= DC_POS_ZERO;
11888 NativeMask |= DC_NEG_SUBNORM;
11890 NativeMask |= DC_POS_SUBNORM;
11893 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11895 TestOp, Dl, MVT::i32,
11904 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11906 uint64_t RHSC =
Op.getConstantOperandVal(1);
11909 if (
LHS.getValueType() == MVT::ppcf128) {
11933 bool Future = Subtarget.isISAFuture();
11936 "Mask predication not supported");
11939 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11940 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11944 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11947 VPLD->getMemoryVT(), VPLD->getMemOperand());
11954 "Mask predication not supported");
11959 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11960 bool Future = Subtarget.isISAFuture();
11961 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11964 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11967 SDVTList Tys = DAG.
getVTList(MVT::Other);
11970 VPST->getMemoryVT(), VPST->getMemOperand());
11981 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11983 int64_t
IntVal =
Op.getConstantOperandVal(0);
11984 if (IntVal >= -16 && IntVal <= 15)
11990 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11995 MachineMemOperand *MMO =
11997 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
12000 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
12004 return Bits.getValue(0);
12020 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12025 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12032 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
12033 MachinePointerInfo());
12040 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
12046 "Should only be called for ISD::INSERT_VECTOR_ELT");
12050 EVT VT =
Op.getValueType();
12055 if (VT == MVT::v2f64 &&
C)
12058 if (Subtarget.hasP9Vector()) {
12067 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12073 BitcastLoad,
Op.getOperand(2));
12074 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12078 if (Subtarget.isISA3_1()) {
12079 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12083 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12084 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12094 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12097 unsigned InsertAtElement =
C->getZExtValue();
12098 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12099 if (Subtarget.isLittleEndian()) {
12100 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12102 return DAG.
getNode(PPCISD::VECINSERT, dl, VT, V1, Mtvsrz,
12114 EVT VT =
Op.getValueType();
12115 bool IsV1024i1 = VT == MVT::v1024i1;
12116 bool IsV2048i1 = VT == MVT::v2048i1;
12120 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12122 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12123 "Dense Math support required.");
12124 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12133 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12134 MachineMemOperand *NewMMO =
12142 DAG.
getVTList(MVT::v256i1, MVT::Other),
12143 LoadOps, MVT::v256i1, NewMMO);
12148 if (Subtarget.isLittleEndian()) {
12149 std::reverse(Loads.
begin(), Loads.
end());
12150 std::reverse(LoadChains.
begin(), LoadChains.
end());
12162 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12168 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12171 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12180 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12183 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12188 {RC, Lo, LoSub, Hi, HiSub}),
12198 EVT VT =
Op.getValueType();
12200 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12201 return LowerDMFVectorLoad(
Op, DAG);
12203 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12207 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12208 "Type unsupported without MMA");
12209 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12210 "Type unsupported without paired vector support");
12214 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12223 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12225 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12234 if (Subtarget.isLittleEndian()) {
12235 std::reverse(Loads.
begin(), Loads.
end());
12236 std::reverse(LoadChains.
begin(), LoadChains.
end());
12240 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12256 bool IsV1024i1 = VT == MVT::v1024i1;
12257 bool IsV2048i1 = VT == MVT::v2048i1;
12261 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12263 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12264 "Dense Math support required.");
12265 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12267 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12270 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12275 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12279 MachineSDNode *ExtNode =
12283 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12289 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12295 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12301 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12306 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12311 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12316 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12320 MachineSDNode *ExtNode =
12321 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12325 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12328 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12332 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12337 if (Subtarget.isLittleEndian())
12338 std::reverse(Values.
begin(), Values.
end());
12340 SDVTList Tys = DAG.
getVTList(MVT::Other);
12342 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12346 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12347 MachineMemOperand *NewMMO =
12354 Ops[2] = Values[Idx];
12356 MVT::v256i1, NewMMO);
12372 EVT StoreVT =
Value.getValueType();
12374 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12375 return LowerDMFVectorStore(
Op, DAG);
12377 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12381 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12382 "Type unsupported without MMA");
12383 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12384 "Type unsupported without paired vector support");
12388 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12396 unsigned NumVecs = 2;
12397 if (StoreVT == MVT::v512i1) {
12398 if (Subtarget.isISAFuture()) {
12399 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12401 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12404 Value2 =
SDValue(ExtNode, 1);
12409 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12410 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12412 if (Subtarget.isISAFuture()) {
12413 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12414 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12415 Idx > 1 ? Value2 :
Value,
12418 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12422 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12436 if (
Op.getValueType() == MVT::v4i32) {
12453 LHS,
RHS, DAG, dl, MVT::v4i32);
12456 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12461 }
else if (
Op.getValueType() == MVT::v16i8) {
12463 bool isLittleEndian = Subtarget.isLittleEndian();
12467 LHS,
RHS, DAG, dl, MVT::v8i16);
12472 LHS,
RHS, DAG, dl, MVT::v8i16);
12480 for (
unsigned i = 0; i != 8; ++i) {
12481 if (isLittleEndian) {
12483 Ops[i*2+1] = 2*i+16;
12486 Ops[i*2+1] = 2*i+1+16;
12489 if (isLittleEndian)
12499 bool IsStrict =
Op->isStrictFPOpcode();
12500 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12501 !Subtarget.hasP9Vector())
12511 "Should only be called for ISD::FP_EXTEND");
12515 if (
Op.getValueType() != MVT::v2f64 ||
12516 Op.getOperand(0).getValueType() != MVT::v2f32)
12528 "Node should have 2 operands with second one being a constant!");
12540 int DWord = Idx >> 1;
12543 if (Subtarget.isLittleEndian())
12546 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12560 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12562 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12563 LD->getMemoryVT(),
LD->getMemOperand());
12568 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12573 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12575 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12576 LD->getMemoryVT(),
LD->getMemOperand());
12577 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12588 if (STI.useCRBits())
12605 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12606 if (STI.useCRBits())
12614 SDNode *
N =
Op.getNode();
12615 EVT VT =
N->getValueType(0);
12616 EVT CarryType =
N->getValueType(1);
12617 unsigned Opc =
N->getOpcode();
12619 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12621 N->getOperand(0),
N->getOperand(1));
12633 SDNode *
N =
Op.getNode();
12634 unsigned Opc =
N->getOpcode();
12635 EVT VT =
N->getValueType(0);
12636 EVT CarryType =
N->getValueType(1);
12637 SDValue CarryOp =
N->getOperand(2);
12639 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12645 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12659 EVT VT =
Op.getNode()->getValueType(0);
12685 EVT VT =
Op.getNode()->getValueType(0);
12714 EVT OpVT =
A.getValueType();
12715 EVT ResVT =
Op.getValueType();
12720 if (Subtarget.isPPC64() && OpVT == MVT::i32) {
12730 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12748 switch (
Op.getOpcode()) {
12768 return LowerSSUBO(
Op, DAG);
12770 return LowerSADDO(
Op, DAG);
12782 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12803 return LowerSET_ROUNDING(
Op, DAG);
12810 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12811 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12823 return LowerFP_ROUND(
Op, DAG);
12837 return LowerINTRINSIC_VOID(
Op, DAG);
12839 return LowerBSWAP(
Op, DAG);
12841 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12843 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12845 return LowerIS_FPCLASS(
Op, DAG);
12848 return LowerADDSUBO(
Op, DAG);
12851 return LowerADDSUBO_CARRY(
Op, DAG);
12853 return LowerUCMP(
Op, DAG);
12859 if (
Op->getFlags().hasNoFPExcept())
12863 return LowerVP_LOAD(
Op, DAG);
12864 case ISD::VP_STORE:
12865 return LowerVP_STORE(
Op, DAG);
12873 switch (
N->getOpcode()) {
12875 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12892 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12895 assert(
N->getValueType(0) == MVT::i1 &&
12896 "Unexpected result type for CTR decrement intrinsic");
12898 N->getValueType(0));
12908 switch (
N->getConstantOperandVal(0)) {
12909 case Intrinsic::ppc_pack_longdouble:
12911 N->getOperand(2),
N->getOperand(1)));
12913 case Intrinsic::ppc_maxfe:
12914 case Intrinsic::ppc_minfe:
12915 case Intrinsic::ppc_fnmsub:
12916 case Intrinsic::ppc_convert_f128_to_ppcf128:
12923 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12926 EVT VT =
N->getValueType(0);
12928 if (VT == MVT::i64) {
12941 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12945 Results.push_back(LoweredValue);
12946 if (
N->isStrictFPOpcode())
12951 if (!
N->getValueType(0).isVector())
12984 return Builder.CreateIntrinsic(Id, {});
12990 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12992 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12993 "Only 8/16/32/64-bit atomic loads supported");
12999 IntID = Intrinsic::ppc_lbarx;
13000 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13003 IntID = Intrinsic::ppc_lharx;
13004 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13007 IntID = Intrinsic::ppc_lwarx;
13010 IntID = Intrinsic::ppc_ldarx;
13014 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
13016 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13027 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13028 "Only 8/16/32/64-bit atomic loads supported");
13034 IntID = Intrinsic::ppc_stbcx;
13035 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13038 IntID = Intrinsic::ppc_sthcx;
13039 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13042 IntID = Intrinsic::ppc_stwcx;
13045 IntID = Intrinsic::ppc_stdcx;
13049 if (SZ == 8 || SZ == 16)
13050 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13052 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13054 return Builder.CreateXor(
Call, Builder.getInt32(1));
13077 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
13087 unsigned BinOpcode,
13088 unsigned CmpOpcode,
13089 unsigned CmpPred)
const {
13094 unsigned AtomicSize =
MI.getOperand(3).getImm();
13096 auto LoadMnemonic = PPC::LDARX;
13097 auto StoreMnemonic = PPC::STDCX;
13098 switch (AtomicSize) {
13102 LoadMnemonic = PPC::LBARX;
13103 StoreMnemonic = PPC::STBCX;
13104 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13107 LoadMnemonic = PPC::LHARX;
13108 StoreMnemonic = PPC::STHCX;
13109 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13112 LoadMnemonic = PPC::LWARX;
13113 StoreMnemonic = PPC::STWCX;
13116 LoadMnemonic = PPC::LDARX;
13117 StoreMnemonic = PPC::STDCX;
13125 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13136 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13138 F->insert(It, loopMBB);
13140 F->insert(It, loop2MBB);
13141 F->insert(It, exitMBB);
13147 Register TmpReg = (!BinOpcode) ? incr :
13148 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13149 : &PPC::GPRCRegClass);
13174 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13179 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13181 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13182 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13183 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13213 switch(
MI.getOpcode()) {
13217 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13218 &
MI.getMF()->getRegInfo());
13242 case PPC::EXTSB8_32_64:
13243 case PPC::EXTSB8_rec:
13244 case PPC::EXTSB_rec:
13247 case PPC::EXTSH8_32_64:
13248 case PPC::EXTSH8_rec:
13249 case PPC::EXTSH_rec:
13251 case PPC::EXTSWSLI:
13252 case PPC::EXTSWSLI_32_64:
13253 case PPC::EXTSWSLI_32_64_rec:
13254 case PPC::EXTSWSLI_rec:
13255 case PPC::EXTSW_32:
13256 case PPC::EXTSW_32_64:
13257 case PPC::EXTSW_32_64_rec:
13258 case PPC::EXTSW_rec:
13261 case PPC::SRAWI_rec:
13262 case PPC::SRAW_rec:
13272 unsigned OpIdx,
bool IsByte,
13277 bool IsSignExtended =
13280 if (!IsSignExtended) {
13281 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13283 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13285 MI.getOperand(
OpIdx).setReg(ValueReg);
13291 unsigned CmpOpcode,
unsigned CmpPred)
const {
13295 assert(!Subtarget.hasPartwordAtomics() &&
13296 "Assumes that part-word atomics are not available");
13304 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13305 if (CmpOpcode == PPC::CMPW)
13313 bool is64bit = Subtarget.isPPC64();
13314 bool isLittleEndian = Subtarget.isLittleEndian();
13315 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13326 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13328 F->insert(It, loopMBB);
13330 F->insert(It, loop2MBB);
13331 F->insert(It, exitMBB);
13337 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13340 Register PtrReg = RegInfo.createVirtualRegister(RC);
13341 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13343 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13344 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13345 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13346 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13347 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13348 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13349 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13350 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13351 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13352 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13355 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13382 if (ptrA != ZeroReg) {
13383 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13384 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13392 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13393 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13396 .
addImm(is8bit ? 28 : 27);
13397 if (!isLittleEndian)
13398 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13400 .
addImm(is8bit ? 24 : 16);
13402 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13407 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13417 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13421 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13426 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13430 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13433 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13440 Register SReg = RegInfo.createVirtualRegister(GPRC);
13441 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13445 unsigned ValueReg = SReg;
13446 unsigned CmpReg = Incr2Reg;
13447 if (CmpOpcode == PPC::CMPW) {
13448 ValueReg = RegInfo.createVirtualRegister(GPRC);
13449 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13452 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13453 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13455 ValueReg = ValueSReg;
13487 .
addImm(is8bit ? 24 : 16)
13508 Register DstReg =
MI.getOperand(0).getReg();
13510 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13515 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13516 "Invalid Pointer Size!");
13565 Register BufReg =
MI.getOperand(1).getReg();
13567 if (Subtarget.is64BitELFABI()) {
13580 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13582 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13585 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13608 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13611 if (Subtarget.isPPC64()) {
13629 TII->get(PPC::PHI), DstReg)
13633 MI.eraseFromParent();
13647 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13648 "Invalid Pointer Size!");
13651 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13654 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13655 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13669 Register BufReg =
MI.getOperand(0).getReg();
13674 if (PVT == MVT::i64) {
13686 if (PVT == MVT::i64) {
13698 if (PVT == MVT::i64) {
13710 if (PVT == MVT::i64) {
13722 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13732 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13735 MI.eraseFromParent();
13751 "Unexpected stack alignment");
13755 unsigned StackProbeSize =
13758 StackProbeSize &= ~(StackAlign - 1);
13759 return StackProbeSize ? StackProbeSize : StackAlign;
13771 const bool isPPC64 = Subtarget.isPPC64();
13803 MF->
insert(MBBIter, TestMBB);
13804 MF->
insert(MBBIter, BlockMBB);
13805 MF->
insert(MBBIter, TailMBB);
13810 Register DstReg =
MI.getOperand(0).getReg();
13811 Register NegSizeReg =
MI.getOperand(1).getReg();
13823 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13829 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13830 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13832 .
addDef(ActualNegSizeReg)
13834 .
add(
MI.getOperand(2))
13835 .
add(
MI.getOperand(3));
13841 .
addReg(ActualNegSizeReg);
13844 int64_t NegProbeSize = -(int64_t)ProbeSize;
13850 .
addImm(NegProbeSize >> 16);
13854 .
addImm(NegProbeSize & 0xFFFF);
13863 .
addReg(ActualNegSizeReg)
13872 .
addReg(ActualNegSizeReg);
13882 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13909 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13910 MaxCallFrameSizeReg)
13911 .
add(
MI.getOperand(2))
13912 .
add(
MI.getOperand(3));
13913 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13915 .
addReg(MaxCallFrameSizeReg);
13921 MBB->addSuccessor(TestMBB);
13924 MI.eraseFromParent();
13926 ++NumDynamicAllocaProbed;
13934static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
13937 case PPC::SELECT_CC_I4:
13938 case PPC::SELECT_CC_I8:
13939 case PPC::SELECT_CC_F4:
13940 case PPC::SELECT_CC_F8:
13941 case PPC::SELECT_CC_F16:
13942 case PPC::SELECT_CC_VRRC:
13943 case PPC::SELECT_CC_VSFRC:
13944 case PPC::SELECT_CC_VSSRC:
13945 case PPC::SELECT_CC_VSRC:
13946 case PPC::SELECT_CC_SPE4:
13947 case PPC::SELECT_CC_SPE:
13950 case PPC::SELECT_I4:
13951 case PPC::SELECT_I8:
13952 case PPC::SELECT_F4:
13953 case PPC::SELECT_F8:
13954 case PPC::SELECT_F16:
13955 case PPC::SELECT_SPE:
13956 case PPC::SELECT_SPE4:
13957 case PPC::SELECT_VRRC:
13958 case PPC::SELECT_VSFRC:
13959 case PPC::SELECT_VSSRC:
13960 case PPC::SELECT_VSRC:
13961 return !CheckOnlyCC;
13977 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
13980 if (Subtarget.hasISEL() &&
13981 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13982 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13983 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13985 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13986 MI.getOpcode() == PPC::SELECT_CC_I8)
13987 Cond.push_back(
MI.getOperand(4));
13990 Cond.push_back(
MI.getOperand(1));
13993 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13994 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13995 MI.eraseFromParent();
14008 F->insert(It, copy0MBB);
14009 F->insert(It, sinkMBB);
14017 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14033 .
addImm(
MI.getOperand(4).getImm())
14034 .
addReg(
MI.getOperand(1).getReg())
14038 .
addReg(
MI.getOperand(1).getReg())
14048 .
addReg(
MI.getOperand(3).getReg())
14050 .
addReg(
MI.getOperand(2).getReg())
14052 MI.eraseFromParent();
14067 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14068 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14069 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14070 F->insert(It, loop1MBB);
14071 F->insert(It, loop2MBB);
14072 F->insert(It, exitMBB);
14107 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14109 unsigned LoadMnemonic = PPC::LDARX;
14110 unsigned StoreMnemonic = PPC::STDCX;
14111 switch (
MI.getOpcode()) {
14114 case PPC::ATOMIC_CMP_SWAP_I8:
14115 LoadMnemonic = PPC::LBARX;
14116 StoreMnemonic = PPC::STBCX;
14117 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14119 case PPC::ATOMIC_CMP_SWAP_I16:
14120 LoadMnemonic = PPC::LHARX;
14121 StoreMnemonic = PPC::STHCX;
14122 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14124 case PPC::ATOMIC_CMP_SWAP_I32:
14125 LoadMnemonic = PPC::LWARX;
14126 StoreMnemonic = PPC::STWCX;
14128 case PPC::ATOMIC_CMP_SWAP_I64:
14129 LoadMnemonic = PPC::LDARX;
14130 StoreMnemonic = PPC::STDCX;
14138 Register oldval =
MI.getOperand(3).getReg();
14139 Register newval =
MI.getOperand(4).getReg();
14153 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14221 bool is64bit = Subtarget.isPPC64();
14223 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14228 Register oldval =
MI.getOperand(3).getReg();
14229 Register newval =
MI.getOperand(4).getReg();
14237 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14242 return RegInfo.createVirtualRegister(RC);
14246 Register Shift1Reg = createVReg(GPRC);
14247 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14248 Register NewVal2Reg = createVReg(GPRC);
14249 Register NewVal3Reg = createVReg(GPRC);
14250 Register OldVal2Reg = createVReg(GPRC);
14251 Register OldVal3Reg = createVReg(GPRC);
14252 Register MaskReg = createVReg(GPRC);
14253 Register Mask2Reg = createVReg(GPRC);
14254 Register Mask3Reg = createVReg(GPRC);
14255 Register Tmp2Reg = createVReg(GPRC);
14256 Register Tmp4Reg = createVReg(GPRC);
14257 Register TmpDestReg = createVReg(GPRC);
14258 Register TmpReg = createVReg(GPRC);
14259 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14260 Register CrReg = createVReg(&PPC::CRRCRegClass);
14264 if (ptrA != ZeroReg) {
14265 Ptr1Reg = createVReg(RC);
14266 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14273 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14274 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14277 .
addImm(is8bit ? 28 : 27);
14278 if (!isLittleEndian)
14279 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14281 .
addImm(is8bit ? 24 : 16);
14283 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14288 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14295 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14298 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14305 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14309 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14312 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14315 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14325 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14346 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14391 switch (
MI.getOpcode()) {
14392 case TargetOpcode::STACKMAP:
14394 case TargetOpcode::PATCHPOINT:
14400 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14404 case PPC::EH_SjLj_SetJmp32:
14405 case PPC::EH_SjLj_SetJmp64:
14408 case PPC::EH_SjLj_LongJmp32:
14409 case PPC::EH_SjLj_LongJmp64:
14412 case PPC::ReadTB: {
14428 F->insert(It, readMBB);
14429 F->insert(It, sinkMBB);
14440 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14448 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14450 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14462 case PPC::ATOMIC_LOAD_ADD_NOWP:
14465 case PPC::ATOMIC_LOAD_ADD:
14468 case PPC::ATOMIC_LOAD_ADD_I64:
14471 case PPC::ATOMIC_LOAD_AND_NOWP:
14474 case PPC::ATOMIC_LOAD_AND:
14477 case PPC::ATOMIC_LOAD_AND_I64:
14480 case PPC::ATOMIC_LOAD_OR_NOWP:
14483 case PPC::ATOMIC_LOAD_OR:
14486 case PPC::ATOMIC_LOAD_OR_I64:
14489 case PPC::ATOMIC_LOAD_XOR_NOWP:
14492 case PPC::ATOMIC_LOAD_XOR:
14495 case PPC::ATOMIC_LOAD_XOR_I64:
14498 case PPC::ATOMIC_LOAD_NAND_NOWP:
14501 case PPC::ATOMIC_LOAD_NAND:
14504 case PPC::ATOMIC_LOAD_NAND_I64:
14507 case PPC::ATOMIC_LOAD_SUB_NOWP:
14510 case PPC::ATOMIC_LOAD_SUB:
14513 case PPC::ATOMIC_LOAD_SUB_I64:
14516 case PPC::ATOMIC_LOAD_MIN_NOWP:
14519 case PPC::ATOMIC_LOAD_MIN:
14522 case PPC::ATOMIC_LOAD_MIN_I64:
14525 case PPC::ATOMIC_LOAD_MAX_NOWP:
14528 case PPC::ATOMIC_LOAD_MAX:
14531 case PPC::ATOMIC_LOAD_MAX_I64:
14534 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14537 case PPC::ATOMIC_LOAD_UMIN:
14540 case PPC::ATOMIC_LOAD_UMIN_I64:
14543 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14546 case PPC::ATOMIC_LOAD_UMAX:
14549 case PPC::ATOMIC_LOAD_UMAX_I64:
14552 case PPC::ATOMIC_SWAP_NOWP:
14555 case PPC::ATOMIC_SWAP:
14556 case PPC::ATOMIC_SWAP_I64:
14559 case PPC::ATOMIC_CMP_SWAP_I32:
14560 case PPC::ATOMIC_CMP_SWAP_I64:
14561 case PPC::ATOMIC_CMP_SWAP_I8:
14562 case PPC::ATOMIC_CMP_SWAP_I16: {
14564 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14565 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14566 (Subtarget.hasPartwordAtomics() &&
14567 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14568 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14576 case PPC::FADDrtz: {
14586 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14601 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14611 case PPC::ANDI_rec_1_EQ_BIT:
14612 case PPC::ANDI_rec_1_GT_BIT:
14613 case PPC::ANDI_rec_1_EQ_BIT8:
14614 case PPC::ANDI_rec_1_GT_BIT8: {
14615 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14616 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14619 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14620 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14623 Register Dest = RegInfo.createVirtualRegister(
14624 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14628 .
addReg(
MI.getOperand(1).getReg())
14631 MI.getOperand(0).getReg())
14632 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14635 case PPC::TCHECK_RET: {
14638 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14641 MI.getOperand(0).getReg())
14645 case PPC::TBEGIN_RET: {
14647 unsigned Imm =
MI.getOperand(1).getImm();
14650 MI.getOperand(0).getReg())
14654 case PPC::SETRNDi: {
14656 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14660 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14662 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14673 unsigned Mode =
MI.getOperand(1).getImm();
14674 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14678 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14683 case PPC::SETRND: {
14691 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14692 if (Subtarget.hasDirectMove()) {
14693 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14697 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14700 if (RC == &PPC::F8RCRegClass) {
14702 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14703 "Unsupported RegClass.");
14705 StoreOp = PPC::STFD;
14709 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14710 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14711 "Unsupported RegClass.");
14744 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14747 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14759 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14761 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14763 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14764 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14769 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14770 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14775 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14776 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14782 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14783 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14794 case PPC::SETFLM: {
14798 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14800 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14802 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14805 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14813 case PPC::PROBED_ALLOCA_32:
14814 case PPC::PROBED_ALLOCA_64:
14817 case PPC::SPLIT_QUADWORD: {
14824 .
addUse(Src, {}, PPC::sub_gp8_x1);
14827 .
addUse(Src, {}, PPC::sub_gp8_x0);
14830 case PPC::LQX_PSEUDO:
14831 case PPC::STQX_PSEUDO: {
14837 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14843 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14844 :
TII->get(PPC::STQ))
14854 MI.eraseFromParent();
14867 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14870 return RefinementSteps;
14877 EVT VT =
Op.getValueType();
14880 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14904PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14907 EVT VT =
Op.getValueType();
14908 if (VT != MVT::f64 &&
14909 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14912 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
14916 int Enabled,
int &RefinementSteps,
14917 bool &UseOneConstNR,
14918 bool Reciprocal)
const {
14920 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14921 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14922 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14923 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14929 UseOneConstNR = !Subtarget.needsTwoConstNR();
14930 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
14937 int &RefinementSteps)
const {
14939 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14940 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14941 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14942 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14945 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
14961 switch (Subtarget.getCPUDirective()) {
14988 unsigned Bytes,
int Dist,
15002 if (FS != BFS || FS != (
int)Bytes)
return false;
15007 int64_t Offset1 = 0, Offset2 = 0;
15010 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15020 if (isGA1 && isGA2 && GV1 == GV2)
15021 return Offset1 == (Offset2 + Dist*Bytes);
15028 unsigned Bytes,
int Dist,
15031 EVT VT = LS->getMemoryVT();
15038 switch (
N->getConstantOperandVal(1)) {
15039 default:
return false;
15040 case Intrinsic::ppc_altivec_lvx:
15041 case Intrinsic::ppc_altivec_lvxl:
15042 case Intrinsic::ppc_vsx_lxvw4x:
15043 case Intrinsic::ppc_vsx_lxvw4x_be:
15046 case Intrinsic::ppc_vsx_lxvd2x:
15047 case Intrinsic::ppc_vsx_lxvd2x_be:
15050 case Intrinsic::ppc_altivec_lvebx:
15053 case Intrinsic::ppc_altivec_lvehx:
15056 case Intrinsic::ppc_altivec_lvewx:
15066 switch (
N->getConstantOperandVal(1)) {
15067 default:
return false;
15068 case Intrinsic::ppc_altivec_stvx:
15069 case Intrinsic::ppc_altivec_stvxl:
15070 case Intrinsic::ppc_vsx_stxvw4x:
15073 case Intrinsic::ppc_vsx_stxvd2x:
15076 case Intrinsic::ppc_vsx_stxvw4x_be:
15079 case Intrinsic::ppc_vsx_stxvd2x_be:
15082 case Intrinsic::ppc_altivec_stvebx:
15085 case Intrinsic::ppc_altivec_stvehx:
15088 case Intrinsic::ppc_altivec_stvewx:
15105 SDValue Chain = LD->getChain();
15106 EVT VT = LD->getMemoryVT();
15115 while (!Queue.empty()) {
15116 SDNode *ChainNext = Queue.pop_back_val();
15117 if (!Visited.
insert(ChainNext).second)
15124 if (!Visited.
count(ChainLD->getChain().getNode()))
15125 Queue.push_back(ChainLD->getChain().getNode());
15127 for (
const SDUse &O : ChainNext->
ops())
15128 if (!Visited.
count(O.getNode()))
15129 Queue.push_back(O.getNode());
15131 LoadRoots.
insert(ChainNext);
15142 for (
SDNode *
I : LoadRoots) {
15143 Queue.push_back(
I);
15145 while (!Queue.empty()) {
15146 SDNode *LoadRoot = Queue.pop_back_val();
15147 if (!Visited.
insert(LoadRoot).second)
15159 Queue.push_back(U);
15192 auto Final = Shifted;
15203 DAGCombinerInfo &DCI)
const {
15206 SelectionDAG &DAG = DCI.DAG;
15211 if (!DCI.isAfterLegalizeDAG())
15216 for (
const SDNode *U :
N->users())
15221 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15225 if (OpSize <
Size) {
15243 DAGCombinerInfo &DCI)
const {
15244 SelectionDAG &DAG = DCI.DAG;
15247 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15258 N->getValueType(0) != MVT::i1)
15261 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15262 N->getOperand(0).getValueType() != MVT::i64)
15272 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15283 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15306 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15307 N->getOperand(0).getOpcode() !=
ISD::OR &&
15308 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15318 N->getOperand(1).getOpcode() !=
ISD::AND &&
15319 N->getOperand(1).getOpcode() !=
ISD::OR &&
15320 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15331 SmallPtrSet<SDNode *, 16> Visited;
15333 for (
unsigned i = 0; i < 2; ++i) {
15337 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15349 while (!BinOps.
empty()) {
15357 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15391 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15395 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15396 if (User !=
N && !Visited.
count(User))
15405 if (
User->getOperand(0) == Inputs[i])
15408 if (
User->getOperand(0) == Inputs[i] ||
15409 User->getOperand(1) == Inputs[i])
15415 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15416 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15417 if (User !=
N && !Visited.
count(User))
15426 if (
User->getOperand(0) == PromOps[i])
15429 if (
User->getOperand(0) == PromOps[i] ||
15430 User->getOperand(1) == PromOps[i])
15437 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15446 std::list<HandleSDNode> PromOpHandles;
15447 for (
auto &PromOp : PromOps)
15448 PromOpHandles.emplace_back(PromOp);
15455 while (!PromOpHandles.empty()) {
15456 SDValue PromOp = PromOpHandles.back().getValue();
15457 PromOpHandles.pop_back();
15466 PromOpHandles.emplace_front(PromOp);
15480 default:
C = 0;
break;
15493 PromOpHandles.emplace_front(PromOp);
15500 for (
unsigned i = 0; i < 2; ++i)
15510 return N->getOperand(0);
15518 DAGCombinerInfo &DCI)
const {
15519 SelectionDAG &DAG = DCI.DAG;
15536 if (
N->getValueType(0) != MVT::i32 &&
15537 N->getValueType(0) != MVT::i64)
15540 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15541 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15544 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15545 N->getOperand(0).getOpcode() !=
ISD::OR &&
15546 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15553 SmallPtrSet<SDNode *, 16> Visited;
15557 while (!BinOps.
empty()) {
15565 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15591 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15596 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15601 if (User !=
N && !Visited.
count(User))
15607 if (
User->getOperand(0) == Inputs[i])
15608 SelectTruncOp[0].
insert(std::make_pair(User,
15609 User->getOperand(0).getValueType()));
15611 if (
User->getOperand(0) == Inputs[i])
15612 SelectTruncOp[0].
insert(std::make_pair(User,
15613 User->getOperand(0).getValueType()));
15614 if (
User->getOperand(1) == Inputs[i])
15615 SelectTruncOp[1].
insert(std::make_pair(User,
15616 User->getOperand(1).getValueType()));
15621 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15623 if (User !=
N && !Visited.
count(User))
15629 if (
User->getOperand(0) == PromOps[i])
15630 SelectTruncOp[0].
insert(std::make_pair(User,
15631 User->getOperand(0).getValueType()));
15633 if (
User->getOperand(0) == PromOps[i])
15634 SelectTruncOp[0].
insert(std::make_pair(User,
15635 User->getOperand(0).getValueType()));
15636 if (
User->getOperand(1) == PromOps[i])
15637 SelectTruncOp[1].
insert(std::make_pair(User,
15638 User->getOperand(1).getValueType()));
15643 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15644 bool ReallyNeedsExt =
false;
15648 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15653 Inputs[i].getOperand(0).getValueSizeInBits();
15654 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15659 OpBits-PromBits))) ||
15662 (OpBits-(PromBits-1)))) {
15663 ReallyNeedsExt =
true;
15671 std::list<HandleSDNode> PromOpHandles;
15672 for (
auto &PromOp : PromOps)
15673 PromOpHandles.emplace_back(PromOp);
15677 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15684 SDValue InSrc = Inputs[i].getOperand(0);
15702 while (!PromOpHandles.empty()) {
15704 PromOpHandles.pop_back();
15708 default:
C = 0;
break;
15721 PromOpHandles.emplace_front(PromOp);
15731 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15733 PromOpHandles.emplace_front(PromOp);
15741 for (
unsigned i = 0; i < 2; ++i) {
15759 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15760 if (SI0 != SelectTruncOp[0].
end())
15762 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15763 if (SI1 != SelectTruncOp[1].
end())
15772 if (!ReallyNeedsExt)
15773 return N->getOperand(0);
15780 N->getValueSizeInBits(0), PromBits),
15781 dl,
N->getValueType(0)));
15784 "Invalid extension type");
15787 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15797 auto isValidForConvert = [](
SDValue &Operand) {
15816 if (LoadNode->isVolatile())
15837 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
15847 "CC mus be ISD::SETNE or ISD::SETEQ");
15849 auto getV16i8Load = [&](
const SDValue &Operand) {
15857 DAG.
getLoad(MVT::v16i8,
DL, LoadNode->getChain(),
15858 LoadNode->getBasePtr(), LoadNode->getMemOperand());
15899 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
15900 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
15903 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
15906 IntrID, CRSel, LHSVec, RHSVec);
15909 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
15927 auto IsAndWithOne = [](
SDValue &V) {
15938 auto IsCompareWithZero = [](
SDValue &V) {
15945 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
15946 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
15963 auto MakeXor1 = [&](
SDValue V) {
15964 EVT VT = V.getValueType();
15971 return MakeXor1(
LHS);
15974 return MakeXor1(
RHS);
15991 DAGCombinerInfo &DCI)
const {
15992 if (Subtarget.isISA3_1())
15995 EVT VT =
N->getValueType(0);
15996 if (VT != MVT::i32 && VT != MVT::i64)
16012 SelectionDAG &DAG = DCI.DAG;
16014 EVT XVT =
X.getValueType();
16016 if ((XVT == MVT::i64 || VT == MVT::i64) && !Subtarget.isPPC64())
16022 if (XVT != MVT::i64 && Subtarget.isPPC64())
16026 EVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16034 Addc, Addc, Carry);
16037 if (OpVT == MVT::i64 && VT == MVT::i32)
16044 DAGCombinerInfo &DCI)
const {
16046 "Should be called with a SETCC node");
16068 SelectionDAG &DAG = DCI.DAG;
16069 EVT VT =
N->getValueType(0);
16070 EVT OpVT =
LHS.getValueType();
16092 return DAGCombineTruncBoolExt(
N, DCI);
16099 Op.getValueType() == MVT::f64;
16111combineElementTruncationToVectorTruncation(
SDNode *
N,
16112 DAGCombinerInfo &DCI)
const {
16114 "Should be called with a BUILD_VECTOR node");
16116 SelectionDAG &DAG = DCI.DAG;
16119 SDValue FirstInput =
N->getOperand(0);
16121 "The input operand must be an fp-to-int conversion.");
16126 if (FirstConversion == PPCISD::FCTIDZ ||
16127 FirstConversion == PPCISD::FCTIDUZ ||
16128 FirstConversion == PPCISD::FCTIWZ ||
16129 FirstConversion == PPCISD::FCTIWUZ) {
16130 bool IsSplat =
true;
16131 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16132 FirstConversion == PPCISD::FCTIWUZ;
16135 EVT TargetVT =
N->getValueType(0);
16136 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16137 SDValue NextOp =
N->getOperand(i);
16138 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16141 if (NextConversion != FirstConversion)
16149 if (
N->getOperand(i) != FirstInput)
16160 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16161 SDValue In =
N->getOperand(i).getOperand(0);
16171 Ops.push_back(Trunc);
16174 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16178 if (FirstConversion == PPCISD::FCTIDZ ||
16179 FirstConversion == PPCISD::FCTIWZ)
16184 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16186 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16204 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16208 if (FullVal == BasePattern)
16209 return std::make_tuple(Uim,
uint8_t{0});
16212 if (FullVal ==
APInt(128, 1))
16213 return std::make_tuple(Uim,
uint8_t{127});
16215 return std::nullopt;
16235 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16239 EVT VT =
Op.getValueType();
16240 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16254 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16264 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16268 uint64_t ElemValue =
C->getZExtValue();
16272 ElemValue &= ((1ULL << ElemBits) - 1);
16276 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16279 APInt ElemAPInt(128, ElemValue);
16280 ElemAPInt <<= BitPos;
16283 FullVal |= ElemAPInt;
16290 const auto &[Uim, ShiftAmount] = *UIMOpt;
16294 if (ShiftAmount == 0) {
16299 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16300 LxvkqInstr.
dump());
16304 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16316 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16319 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16335 "Should be called with a BUILD_VECTOR node");
16340 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16343 bool InputsAreConsecutiveLoads =
true;
16344 bool InputsAreReverseConsecutive =
true;
16345 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16346 SDValue FirstInput =
N->getOperand(0);
16347 bool IsRoundOfExtLoad =
false;
16357 N->getNumOperands() == 1)
16360 if (!IsRoundOfExtLoad)
16365 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16367 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16370 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16376 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16387 InputsAreConsecutiveLoads =
false;
16389 InputsAreReverseConsecutive =
false;
16392 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16397 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16398 "The loads cannot be both consecutive and reverse consecutive.");
16402 if (InputsAreConsecutiveLoads) {
16403 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16407 ReturnSDVal = WideLoad;
16408 }
else if (InputsAreReverseConsecutive) {
16410 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16415 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16423 for (
auto *LD : InputLoads)
16425 return ReturnSDVal;
16436 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16442 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16444 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16446 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16447 CorrectElems = CorrectElems >> 8;
16448 Elems = Elems >> 8;
16455 EVT VT =
N->getValueType(0);
16459 Input.getValueType().getVectorElementType(),
16493 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16519 Elems = Elems << 8;
16528 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16529 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16536 int TgtElemArrayIdx;
16537 int InputSize =
Input.getValueType().getScalarSizeInBits();
16538 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16539 if (InputSize + OutputSize == 40)
16540 TgtElemArrayIdx = 0;
16541 else if (InputSize + OutputSize == 72)
16542 TgtElemArrayIdx = 1;
16543 else if (InputSize + OutputSize == 48)
16544 TgtElemArrayIdx = 2;
16545 else if (InputSize + OutputSize == 80)
16546 TgtElemArrayIdx = 3;
16547 else if (InputSize + OutputSize == 96)
16548 TgtElemArrayIdx = 4;
16552 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16554 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16555 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16556 if (Elems != CorrectElems) {
16572 if (
N->getValueType(0) != MVT::v1i128)
16575 SDValue Operand =
N->getOperand(0);
16582 EVT MemoryType = LD->getMemoryVT();
16586 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16587 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16590 if (!ValidLDType ||
16596 LD->getChain(), LD->getBasePtr(),
16600 DAG.
getVTList(MVT::v1i128, MVT::Other),
16601 LoadOps, MemoryType, LD->getMemOperand());
16605 DAGCombinerInfo &DCI)
const {
16607 "Should be called with a BUILD_VECTOR node");
16609 SelectionDAG &DAG = DCI.DAG;
16612 if (!Subtarget.hasVSX())
16619 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16620 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16635 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16644 if (Subtarget.isISA3_1()) {
16650 if (
N->getValueType(0) != MVT::v2f64)
16661 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16672 if (!Ext1Op || !Ext2Op)
16681 if (FirstElem == 0 && SecondElem == 1)
16682 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16683 else if (FirstElem == 2 && SecondElem == 3)
16684 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16690 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16691 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16696 DAGCombinerInfo &DCI)
const {
16699 "Need an int -> FP conversion node here");
16704 SelectionDAG &DAG = DCI.DAG;
16710 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16712 if (!
Op.getOperand(0).getValueType().isSimple())
16714 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16715 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16718 SDValue FirstOperand(
Op.getOperand(0));
16719 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16720 (FirstOperand.getValueType() == MVT::i8 ||
16721 FirstOperand.getValueType() == MVT::i16);
16722 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16724 bool DstDouble =
Op.getValueType() == MVT::f64;
16725 unsigned ConvOp =
Signed ?
16726 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16727 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
16732 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16735 Ops, MVT::i8, LDN->getMemOperand());
16740 SDValue ExtOps[] = { Ld, WidthConst };
16742 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16744 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16752 if (
Op.getOperand(0).getValueType() == MVT::i32)
16756 "UINT_TO_FP is supported only with FPCVT");
16760 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16765 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16772 Subtarget.hasFPCVT()) ||
16774 SDValue Src =
Op.getOperand(0).getOperand(0);
16775 if (Src.getValueType() == MVT::f32) {
16777 DCI.AddToWorklist(Src.getNode());
16778 }
else if (Src.getValueType() != MVT::f64) {
16790 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16793 DCI.AddToWorklist(
FP.getNode());
16817 switch (
N->getOpcode()) {
16822 Chain = LD->getChain();
16823 Base = LD->getBasePtr();
16824 MMO = LD->getMemOperand();
16843 MVT VecTy =
N->getValueType(0).getSimpleVT();
16851 Chain = Load.getValue(1);
16853 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Load);
16857 if (VecTy != MVT::v2f64) {
16884 switch (
N->getOpcode()) {
16889 Chain = ST->getChain();
16890 Base = ST->getBasePtr();
16891 MMO = ST->getMemOperand();
16911 SDValue Src =
N->getOperand(SrcOpnd);
16912 MVT VecTy = Src.getValueType().getSimpleVT();
16915 if (VecTy != MVT::v2f64) {
16921 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16927 StoreOps, VecTy, MMO);
16934 DAGCombinerInfo &DCI)
const {
16937 unsigned Opcode =
N->getOperand(1).getOpcode();
16939 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16943 &&
"Not a FP_TO_INT Instruction!");
16945 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16946 EVT Op1VT =
N->getOperand(1).getValueType();
16949 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16953 bool ValidTypeForStoreFltAsInt =
16954 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16955 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16958 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16961 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16969 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16984 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16985 for (
int i = 1, e = Mask.size(); i < e; i++) {
16986 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16988 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16990 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17001 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17002 FirstOp =
Op.getOperand(i);
17008 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17009 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17019 Op =
Op.getOperand(0);
17035 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17036 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
17038 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17040 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17041 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17042 int Idx = ShuffV[
I];
17043 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17044 ShuffV[
I] += LHSEltFixup;
17045 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17046 ShuffV[
I] += RHSEltFixup;
17057 SDLoc dl(OrigSToV);
17060 "Expecting a SCALAR_TO_VECTOR here");
17073 "Cannot produce a permuted scalar_to_vector for one element vector");
17075 unsigned ResultInElt = NumElts / 2;
17081 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17086 int HalfVec,
int LHSLastElementDefined,
17087 int RHSLastElementDefined) {
17088 for (
int Index : ShuffV) {
17092 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17093 (Index > LHSLastElementDefined))
17096 if ((RHSLastElementDefined >= 0) &&
17097 (Index > HalfVec + RHSLastElementDefined))
17104 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17105 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17121 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17122 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17125 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17126 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17127 return SToVPermuted;
17147 int NumElts =
LHS.getValueType().getVectorNumElements();
17150 bool IsLittleEndian = Subtarget.isLittleEndian();
17157 if (!Subtarget.hasDirectMove())
17177 SmallVector<int, 16> ShuffV(Mask);
17180 if (SToVLHS || SToVRHS) {
17183 int ShuffleNumElts = ShuffV.
size();
17184 int HalfVec = ShuffleNumElts / 2;
17190 unsigned LHSNumValidElts = HalfVec;
17191 unsigned RHSNumValidElts = HalfVec;
17196 int LHSFirstElt = 0;
17197 int RHSFirstElt = ShuffleNumElts;
17198 int LHSLastElt = -1;
17199 int RHSLastElt = -1;
17207 int LHSScalarSize = 0;
17208 int RHSScalarSize = 0;
17211 if (!IsLittleEndian && LHSScalarSize >= 64)
17216 if (!IsLittleEndian && RHSScalarSize >= 64)
17219 if (LHSScalarSize != 0)
17221 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17222 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17223 if (RHSScalarSize != 0)
17225 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17226 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17237 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17238 LHSNumValidElts, RHSNumValidElts, Subtarget);
17264 if (IsLittleEndian) {
17267 if (Mask[0] < NumElts)
17268 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17272 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17277 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17281 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17286 if (Mask[0] < NumElts)
17287 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17291 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17296 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17300 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17310 if (IsLittleEndian)
17319 DAGCombinerInfo &DCI)
const {
17321 "Not a reverse memop pattern!");
17323 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17326 auto I =
Mask.rbegin();
17327 auto E =
Mask.rend();
17329 for (;
I !=
E; ++
I) {
17337 SelectionDAG &DAG = DCI.DAG;
17340 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17346 if (!Subtarget.hasP9Vector())
17349 if(!IsElementReverse(SVN))
17356 for (SDUse &Use : LSBase->
uses())
17357 if (
Use.getResNo() == 0 &&
17364 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17379 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17388 if (IntrinsicID == Intrinsic::ppc_stdcx)
17390 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17392 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17394 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17403 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17407 if (
LHS->getOpcode() == PPCISD::ADDE &&
17427 SDValue CmpLHS =
N->getOperand(0);
17428 SDValue CmpRHS =
N->getOperand(1);
17429 SDValue TrueVal =
N->getOperand(2);
17430 SDValue FalseVal =
N->getOperand(3);
17444 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17447 SDValue ShiftVal = FalseVal.getOperand(0);
17448 SDValue ShiftAmt = FalseVal.getOperand(1);
17452 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17479 if (CtlzArg != CmpLHS)
17487 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17534 auto isZeroOrOne = [=](
SDValue &V) {
17536 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17541 if (!isZeroOrOne(NonNullConstant))
17551 EVT VType =
N->getValueType(0);
17555 return NewNonNullConstant;
17574 EVT XorVT =
N->getValueType(0);
17575 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17583 if (!XorConst || !XorConst->
isOne()) {
17585 if (!XorConst || !XorConst->
isOne())
17592 if (!
LHS.hasOneUse())
17600 SelectNode =
LHS.getOperand(0);
17614 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17624 if (!ConstOp1 || !ConstOp2)
17628 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17637 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17639 bool ConstOp1IsOne = ConstOp1->
isOne();
17642 {SelectNode.getOperand(0),
17643 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17644 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17645 SelectNode.getOperand(3)}),
17653 switch (
N->getOpcode()) {
17656 return combineADD(
N, DCI);
17688 return combineSHL(
N, DCI);
17690 return combineSRA(
N, DCI);
17692 return combineSRL(
N, DCI);
17694 return combineMUL(
N, DCI);
17696 case PPCISD::FNMSUB:
17697 return combineFMALike(
N, DCI);
17700 return N->getOperand(0);
17704 return N->getOperand(0);
17710 return N->getOperand(0);
17714 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
17722 return DAGCombineExtBoolTrunc(
N, DCI);
17724 return combineTRUNCATE(
N, DCI);
17726 if (
SDValue CSCC = combineSetCC(
N, DCI))
17732 return DAGCombineTruncBoolExt(
N, DCI);
17735 return combineFPToIntToFP(
N, DCI);
17744 EVT Op1VT =
N->getOperand(1).getValueType();
17745 unsigned Opcode =
N->getOperand(1).getOpcode();
17749 SDValue Val = combineStoreFPToInt(
N, DCI);
17763 N->getOperand(1).getNode()->hasOneUse() &&
17764 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17765 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17773 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17780 if (Op1VT.
bitsGT(mVT)) {
17785 if (Op1VT == MVT::i64)
17790 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17810 ST->getBasePtr(), ST->getOffset(), MemVT,
17811 ST->getMemOperand(), ST->getAddressingMode(),
17815 return ST->isUnindexed()
17824 if (Subtarget.needsSwapsForVSXMemOps() &&
17825 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17826 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17833 EVT VT = LD->getValueType(0);
17839 if (Subtarget.needsSwapsForVSXMemOps() &&
17840 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17841 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17852 auto ReplaceTwoFloatLoad = [&]() {
17853 if (VT != MVT::i64)
17868 if (!LD->hasNUsesOfValue(2, 0))
17871 auto UI = LD->user_begin();
17872 while (UI.getUse().getResNo() != 0) ++UI;
17874 while (UI.getUse().getResNo() != 0) ++UI;
17875 SDNode *RightShift = *UI;
17883 if (RightShift->getOpcode() !=
ISD::SRL ||
17885 RightShift->getConstantOperandVal(1) != 32 ||
17886 !RightShift->hasOneUse())
17889 SDNode *Trunc2 = *RightShift->user_begin();
17899 Bitcast->getValueType(0) != MVT::f32)
17905 if (Subtarget.isLittleEndian())
17911 SDValue BasePtr = LD->getBasePtr();
17912 if (LD->isIndexed()) {
17914 "Non-pre-inc AM on PPC?");
17922 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17923 LD->getPointerInfo(), LD->getAlign(),
17924 MMOFlags, LD->getAAInfo());
17930 LD->getPointerInfo().getWithOffset(4),
17933 if (LD->isIndexed()) {
17947 if (ReplaceTwoFloatLoad())
17950 EVT MemVT = LD->getMemoryVT();
17953 if (LD->isUnindexed() && VT.
isVector() &&
17956 !Subtarget.hasP8Vector() &&
17957 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17958 VT == MVT::v4f32))) &&
17959 LD->getAlign() < ABIAlignment) {
17961 SDValue Chain = LD->getChain();
17962 SDValue Ptr = LD->getBasePtr();
17963 bool isLittleEndian = Subtarget.isLittleEndian();
17990 MVT PermCntlTy, PermTy, LDTy;
17991 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17992 : Intrinsic::ppc_altivec_lvsl;
17993 IntrLD = Intrinsic::ppc_altivec_lvx;
17994 IntrPerm = Intrinsic::ppc_altivec_vperm;
17995 PermCntlTy = MVT::v16i8;
17996 PermTy = MVT::v4i32;
18015 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18019 BaseLoadOps, LDTy, BaseMMO);
18028 int IncValue = IncOffset;
18045 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18049 ExtraLoadOps, LDTy, ExtraMMO);
18060 if (isLittleEndian)
18062 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18065 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18068 Perm = Subtarget.hasAltivec()
18083 bool isLittleEndian = Subtarget.isLittleEndian();
18084 unsigned IID =
N->getConstantOperandVal(0);
18085 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18086 : Intrinsic::ppc_altivec_lvsl);
18087 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18094 .zext(
Add.getScalarValueSizeInBits()))) {
18095 SDNode *BasePtr =
Add->getOperand(0).getNode();
18096 for (
SDNode *U : BasePtr->users()) {
18098 U->getConstantOperandVal(0) == IID) {
18109 SDNode *BasePtr =
Add->getOperand(0).getNode();
18110 for (
SDNode *U : BasePtr->users()) {
18113 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18119 V->getConstantOperandVal(0) == IID) {
18131 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18132 IID == Intrinsic::ppc_altivec_vmaxsh ||
18133 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18164 switch (
N->getConstantOperandVal(1)) {
18167 case Intrinsic::ppc_altivec_vsum4sbs:
18168 case Intrinsic::ppc_altivec_vsum4shs:
18169 case Intrinsic::ppc_altivec_vsum4ubs: {
18176 APInt APSplatBits, APSplatUndef;
18177 unsigned SplatBitSize;
18180 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18181 !Subtarget.isLittleEndian());
18183 if (BVNIsConstantSplat && APSplatBits == 0)
18188 case Intrinsic::ppc_vsx_lxvw4x:
18189 case Intrinsic::ppc_vsx_lxvd2x:
18192 if (Subtarget.needsSwapsForVSXMemOps())
18200 if (Subtarget.needsSwapsForVSXMemOps()) {
18201 switch (
N->getConstantOperandVal(1)) {
18204 case Intrinsic::ppc_vsx_stxvw4x:
18205 case Intrinsic::ppc_vsx_stxvd2x:
18214 bool Is64BitBswapOn64BitTgt =
18215 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18217 N->getOperand(0).hasOneUse();
18218 if (IsSingleUseNormalLd &&
18219 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18220 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18231 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18232 MVT::i64 : MVT::i32, MVT::Other),
18233 Ops, LD->getMemoryVT(), LD->getMemOperand());
18237 if (
N->getValueType(0) == MVT::i16)
18254 !IsSingleUseNormalLd)
18259 if (!LD->isSimple())
18261 SDValue BasePtr = LD->getBasePtr();
18263 LD->getPointerInfo(), LD->getAlign());
18268 LD->getMemOperand(), 4, 4);
18272 if (Subtarget.isLittleEndian())
18278 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18287 if (!
N->getOperand(0).hasOneUse() &&
18288 !
N->getOperand(1).hasOneUse() &&
18289 !
N->getOperand(2).hasOneUse()) {
18292 SDNode *VCMPrecNode =
nullptr;
18294 SDNode *LHSN =
N->getOperand(0).getNode();
18296 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18300 VCMPrecNode =
User;
18312 SDNode *FlagUser =
nullptr;
18314 FlagUser ==
nullptr; ++UI) {
18315 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18328 return SDValue(VCMPrecNode, 0);
18339 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18350 auto RHSAPInt = RHS->getAsAPIntVal();
18351 if (!RHSAPInt.isIntN(64))
18354 unsigned Val = RHSAPInt.getZExtValue();
18355 auto isImpossibleCompare = [&]() {
18358 if (Val != 0 && Val != 1) {
18360 return N->getOperand(0);
18363 N->getOperand(0),
N->getOperand(4));
18368 unsigned StoreWidth = 0;
18371 if (
SDValue Impossible = isImpossibleCompare())
18383 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18387 PPCISD::STORE_COND, dl,
18389 MemNode->getMemoryVT(), MemNode->getMemOperand());
18393 if (
N->getOperand(0) == LHS.getValue(1))
18404 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18406 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18412 assert(isDot &&
"Can't compare against a vector result!");
18414 if (
SDValue Impossible = isImpossibleCompare())
18417 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
18424 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18429 switch (LHS.getConstantOperandVal(1)) {
18445 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18448 N->getOperand(4), CompNode.
getValue(1));
18453 return DAGCombineBuildVector(
N, DCI);
18458 return DAGCombineBitcast(
N, DCI);
18469 EVT VT =
N->getValueType(0);
18470 if (VT == MVT::i64 && !Subtarget.isPPC64())
18472 if ((VT != MVT::i32 && VT != MVT::i64) ||
18480 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18500 const APInt &DemandedElts,
18502 unsigned Depth)
const {
18504 switch (
Op.getOpcode()) {
18506 case PPCISD::LBRX: {
18509 Known.
Zero = 0xFFFF0000;
18512 case PPCISD::ADDE: {
18513 if (
Op.getResNo() == 0) {
18518 Known.
Zero = ~1ULL;
18523 switch (
Op.getConstantOperandVal(0)) {
18525 case Intrinsic::ppc_altivec_vcmpbfp_p:
18526 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18527 case Intrinsic::ppc_altivec_vcmpequb_p:
18528 case Intrinsic::ppc_altivec_vcmpequh_p:
18529 case Intrinsic::ppc_altivec_vcmpequw_p:
18530 case Intrinsic::ppc_altivec_vcmpequd_p:
18531 case Intrinsic::ppc_altivec_vcmpequq_p:
18532 case Intrinsic::ppc_altivec_vcmpgefp_p:
18533 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18534 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18535 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18536 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18537 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18538 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18539 case Intrinsic::ppc_altivec_vcmpgtub_p:
18540 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18541 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18542 case Intrinsic::ppc_altivec_vcmpgtud_p:
18543 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18550 switch (
Op.getConstantOperandVal(1)) {
18553 case Intrinsic::ppc_load2r:
18555 Known.
Zero = 0xFFFF0000;
18564 switch (Subtarget.getCPUDirective()) {
18586 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18595 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18597 LoopSize +=
TII->getInstSizeInBytes(J);
18602 if (LoopSize > 16 && LoopSize <= 32)
18616 if (Constraint.
size() == 1) {
18617 switch (Constraint[0]) {
18635 }
else if (Constraint ==
"wc") {
18637 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18638 Constraint ==
"wf" || Constraint ==
"ws" ||
18639 Constraint ==
"wi" || Constraint ==
"ww") {
18652 Value *CallOperandVal =
info.CallOperandVal;
18655 if (!CallOperandVal)
18662 else if ((
StringRef(constraint) ==
"wa" ||
18674 switch (*constraint) {
18704std::pair<unsigned, const TargetRegisterClass *>
18708 if (Constraint.
size() == 1) {
18710 switch (Constraint[0]) {
18712 if (VT == MVT::i64 && Subtarget.isPPC64())
18713 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18714 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18716 if (VT == MVT::i64 && Subtarget.isPPC64())
18717 return std::make_pair(0U, &PPC::G8RCRegClass);
18718 return std::make_pair(0U, &PPC::GPRCRegClass);
18724 if (Subtarget.hasSPE()) {
18725 if (VT == MVT::f32 || VT == MVT::i32)
18726 return std::make_pair(0U, &PPC::GPRCRegClass);
18727 if (VT == MVT::f64 || VT == MVT::i64)
18728 return std::make_pair(0U, &PPC::SPERCRegClass);
18730 if (VT == MVT::f32 || VT == MVT::i32)
18731 return std::make_pair(0U, &PPC::F4RCRegClass);
18732 if (VT == MVT::f64 || VT == MVT::i64)
18733 return std::make_pair(0U, &PPC::F8RCRegClass);
18737 if (Subtarget.hasAltivec() && VT.
isVector())
18738 return std::make_pair(0U, &PPC::VRRCRegClass);
18739 else if (Subtarget.hasVSX())
18741 return std::make_pair(0U, &PPC::VFRCRegClass);
18744 return std::make_pair(0U, &PPC::CRRCRegClass);
18746 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18748 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18749 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18750 Constraint ==
"wf" || Constraint ==
"wi") &&
18751 Subtarget.hasVSX()) {
18755 return std::make_pair(0U, &PPC::VSRCRegClass);
18756 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18757 return std::make_pair(0U, &PPC::VSSRCRegClass);
18758 return std::make_pair(0U, &PPC::VSFRCRegClass);
18759 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18760 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18761 return std::make_pair(0U, &PPC::VSSRCRegClass);
18763 return std::make_pair(0U, &PPC::VSFRCRegClass);
18764 }
else if (Constraint ==
"lr") {
18765 if (VT == MVT::i64)
18766 return std::make_pair(0U, &PPC::LR8RCRegClass);
18768 return std::make_pair(0U, &PPC::LRRCRegClass);
18773 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18777 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18778 int VSNum = atoi(Constraint.
data() + 3);
18779 assert(VSNum >= 0 && VSNum <= 63 &&
18780 "Attempted to access a vsr out of range");
18782 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18783 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18788 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18789 int RegNum = atoi(Constraint.
data() + 2);
18790 if (RegNum > 31 || RegNum < 0)
18792 if (VT == MVT::f32 || VT == MVT::i32)
18793 return Subtarget.hasSPE()
18794 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18795 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18796 if (VT == MVT::f64 || VT == MVT::i64)
18797 return Subtarget.hasSPE()
18798 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18799 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18803 std::pair<unsigned, const TargetRegisterClass *> R =
18812 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18813 PPC::GPRCRegClass.contains(R.first))
18814 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18815 PPC::sub_32, &PPC::G8RCRegClass),
18816 &PPC::G8RCRegClass);
18819 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18820 R.first = PPC::CR0;
18821 R.second = &PPC::CRRCRegClass;
18825 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18826 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18827 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18828 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18829 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18830 "default AIX AltiVec ABI and cannot be used\n";
18840 std::vector<SDValue> &
Ops,
18845 if (Constraint.
size() > 1)
18848 char Letter = Constraint[0];
18863 EVT TCVT = MVT::i64;
18904 if (Result.getNode()) {
18905 Ops.push_back(Result);
18916 if (
I.getNumOperands() <= 1)
18920 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18921 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18922 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18925 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18941 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18953 switch (AM.
Scale) {
18981 unsigned Depth =
Op.getConstantOperandVal(0);
19005 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19013 unsigned Depth =
Op.getConstantOperandVal(0);
19020 bool isPPC64 = PtrVT == MVT::i64;
19026 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19028 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19034 FrameAddr, MachinePointerInfo());
19038#define GET_REGISTER_MATCHER
19039#include "PPCGenAsmMatcher.inc"
19043 bool IsPPC64 = Subtarget.isPPC64();
19055 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19061 Reg = Reg.id() - PPC::R0 + PPC::X0;
19068 if (Subtarget.is32BitELFABI())
19073 if (Subtarget.isAIXABI())
19087 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19103 case Intrinsic::ppc_atomicrmw_xchg_i128:
19104 case Intrinsic::ppc_atomicrmw_add_i128:
19105 case Intrinsic::ppc_atomicrmw_sub_i128:
19106 case Intrinsic::ppc_atomicrmw_nand_i128:
19107 case Intrinsic::ppc_atomicrmw_and_i128:
19108 case Intrinsic::ppc_atomicrmw_or_i128:
19109 case Intrinsic::ppc_atomicrmw_xor_i128:
19110 case Intrinsic::ppc_cmpxchg_i128:
19112 Info.memVT = MVT::i128;
19113 Info.ptrVal =
I.getArgOperand(0);
19115 Info.align =
Align(16);
19120 case Intrinsic::ppc_atomic_load_i128:
19122 Info.memVT = MVT::i128;
19123 Info.ptrVal =
I.getArgOperand(0);
19125 Info.align =
Align(16);
19129 case Intrinsic::ppc_atomic_store_i128:
19131 Info.memVT = MVT::i128;
19132 Info.ptrVal =
I.getArgOperand(2);
19134 Info.align =
Align(16);
19138 case Intrinsic::ppc_altivec_lvx:
19139 case Intrinsic::ppc_altivec_lvxl:
19140 case Intrinsic::ppc_altivec_lvebx:
19141 case Intrinsic::ppc_altivec_lvehx:
19142 case Intrinsic::ppc_altivec_lvewx:
19143 case Intrinsic::ppc_vsx_lxvd2x:
19144 case Intrinsic::ppc_vsx_lxvw4x:
19145 case Intrinsic::ppc_vsx_lxvd2x_be:
19146 case Intrinsic::ppc_vsx_lxvw4x_be:
19147 case Intrinsic::ppc_vsx_lxvl:
19148 case Intrinsic::ppc_vsx_lxvll: {
19151 case Intrinsic::ppc_altivec_lvebx:
19154 case Intrinsic::ppc_altivec_lvehx:
19157 case Intrinsic::ppc_altivec_lvewx:
19160 case Intrinsic::ppc_vsx_lxvd2x:
19161 case Intrinsic::ppc_vsx_lxvd2x_be:
19171 Info.ptrVal =
I.getArgOperand(0);
19174 Info.align =
Align(1);
19179 case Intrinsic::ppc_altivec_stvx:
19180 case Intrinsic::ppc_altivec_stvxl:
19181 case Intrinsic::ppc_altivec_stvebx:
19182 case Intrinsic::ppc_altivec_stvehx:
19183 case Intrinsic::ppc_altivec_stvewx:
19184 case Intrinsic::ppc_vsx_stxvd2x:
19185 case Intrinsic::ppc_vsx_stxvw4x:
19186 case Intrinsic::ppc_vsx_stxvd2x_be:
19187 case Intrinsic::ppc_vsx_stxvw4x_be:
19188 case Intrinsic::ppc_vsx_stxvl:
19189 case Intrinsic::ppc_vsx_stxvll: {
19192 case Intrinsic::ppc_altivec_stvebx:
19195 case Intrinsic::ppc_altivec_stvehx:
19198 case Intrinsic::ppc_altivec_stvewx:
19201 case Intrinsic::ppc_vsx_stxvd2x:
19202 case Intrinsic::ppc_vsx_stxvd2x_be:
19212 Info.ptrVal =
I.getArgOperand(1);
19215 Info.align =
Align(1);
19220 case Intrinsic::ppc_stdcx:
19221 case Intrinsic::ppc_stwcx:
19222 case Intrinsic::ppc_sthcx:
19223 case Intrinsic::ppc_stbcx: {
19225 auto Alignment =
Align(8);
19227 case Intrinsic::ppc_stdcx:
19230 case Intrinsic::ppc_stwcx:
19232 Alignment =
Align(4);
19234 case Intrinsic::ppc_sthcx:
19236 Alignment =
Align(2);
19238 case Intrinsic::ppc_stbcx:
19240 Alignment =
Align(1);
19245 Info.ptrVal =
I.getArgOperand(0);
19247 Info.align = Alignment;
19261 const AttributeList &FuncAttributes)
const {
19265 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19266 if (
Op.isMemset() && Subtarget.hasVSX()) {
19271 if (TailSize > 2 && TailSize <= 4) {
19276 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19281 if (Subtarget.isPPC64()) {
19292 assert(Ty->isIntegerTy());
19294 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19295 return !(BitSize == 0 || BitSize > 64);
19303 return NumBits1 == 64 && NumBits2 == 32;
19311 return NumBits1 == 64 && NumBits2 == 32;
19318 EVT MemVT = LD->getMemoryVT();
19319 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19320 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19336 "invalid fpext types");
19338 if (DestVT == MVT::f128)
19353 unsigned *
Fast)
const {
19367 !Subtarget.allowsUnalignedFPAccess())
19371 if (Subtarget.hasVSX()) {
19372 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19373 VT != MVT::v4f32 && VT != MVT::v4i32)
19380 if (VT == MVT::ppcf128)
19395 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19403 int64_t Imm = ConstNode->getSExtValue();
19424 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19426 switch (Ty->getScalarType()->getTypeID()) {
19431 return Subtarget.hasP9Vector();
19439 if (!
I->hasOneUse())
19443 assert(
User &&
"A single use instruction with no uses.");
19445 switch (
I->getOpcode()) {
19446 case Instruction::FMul: {
19448 if (
User->getOpcode() != Instruction::FSub &&
19449 User->getOpcode() != Instruction::FAdd)
19456 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19457 User->getFastMathFlags().allowContract();
19463 case Instruction::Load: {
19476 if (
User->getOpcode() != Instruction::Store)
19496 static const MCPhysReg ScratchRegs[] = {
19497 PPC::X12, PPC::LR8, PPC::CTR8, 0
19500 return ScratchRegs;
19504 const Constant *PersonalityFn)
const {
19505 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19509 const Constant *PersonalityFn)
const {
19510 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19515 EVT VT ,
unsigned DefinedValues)
const {
19516 if (VT == MVT::v2i64)
19517 return Subtarget.hasDirectMove();
19519 if (Subtarget.hasVSX())
19546 return PPCISD::FNMSUB;
19547 case PPCISD::FNMSUB:
19553 bool LegalOps,
bool OptForSize,
19555 unsigned Depth)
const {
19559 unsigned Opc =
Op.getOpcode();
19560 EVT VT =
Op.getValueType();
19564 case PPCISD::FNMSUB:
19584 if (Flags.hasNoSignedZeros()) {
19588 N0Cost,
Depth + 1);
19592 N1Cost,
Depth + 1);
19594 if (NegN0 && N0Cost <= N1Cost) {
19595 Cost = std::min(N0Cost, N2Cost);
19597 }
else if (NegN1) {
19598 Cost = std::min(N1Cost, N2Cost);
19618 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19624 bool ForCodeSize)
const {
19625 if (!VT.
isSimple() || !Subtarget.hasVSX())
19635 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19640 APSInt IntResult(16,
false);
19645 if (IsExact && IntResult <= 15 && IntResult >= -16)
19647 return Imm.isZero();
19650 return Imm.isPosZero();
19662 unsigned Opcode =
N->getOpcode();
19682 if (Mask->getZExtValue() == OpSizeInBits - 1)
19689 DAGCombinerInfo &DCI)
const {
19690 EVT VT =
N->getValueType(0);
19693 unsigned Opc =
N->getOpcode();
19695 "Unexpected opcode.");
19702 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19706 uint64_t SplatBits = 0;
19707 bool AddSplatCase =
false;
19711 AddSplatCase =
true;
19715 if (!AddSplatCase) {
19719 unsigned SplatBitSize;
19721 APInt APSplatBits, APSplatUndef;
19723 bool BVNIsConstantSplat =
19725 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19726 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19737 if (SplatBits == (EltBits - 1)) {
19741 NewOpc = PPCISD::SHL;
19744 NewOpc = PPCISD::SRL;
19747 NewOpc = PPCISD::SRA;
19751 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19759 if (EltTy != MVT::i64 || SplatBits != 1)
19762 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19765SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19769 if (
N->getValueType(0).isVector())
19770 return combineVectorShift(
N, DCI);
19774 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19777 N->getValueType(0) != MVT::i64)
19792 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19798SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19802 if (
N->getValueType(0).isVector())
19803 return combineVectorShift(
N, DCI);
19808SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19812 if (
N->getValueType(0).isVector())
19813 return combineVectorShift(
N, DCI);
19824 if (!Subtarget.isPPC64())
19830 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19832 Op.getValueType() != MVT::i64)
19836 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19837 Cmp.getOperand(0).getValueType() != MVT::i64)
19841 int64_t NegConstant = 0 -
Constant->getSExtValue();
19850 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19851 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19854 if (LHSHasPattern && !RHSHasPattern)
19856 else if (!LHSHasPattern && !RHSHasPattern)
19860 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19863 SDValue Z = Cmp.getOperand(0);
19865 int64_t NegConstant = 0 -
Constant->getSExtValue();
19878 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19896 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19926 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19929 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
19937 if (!GSDN || !ConstNode)
19965 EVT VT =
N->getValueType(0);
19966 if (!Subtarget.hasVSX())
19970 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
19982 unsigned NumOfEles =
RHS.getNumOperands();
19983 for (
unsigned i = 0; i < NumOfEles; ++i) {
19985 if (!CN || CN->getSExtValue() != 1)
20000SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20022 DAGCombinerInfo &DCI)
const {
20024 if (Subtarget.useCRBits()) {
20026 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20027 return CRTruncValue;
20034 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20037 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20047 EltToExtract = EltToExtract ? 0 : 1;
20057 return DCI.DAG.getNode(
20059 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20064SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20065 SelectionDAG &DAG = DCI.DAG;
20068 if (!ConstOpOrElement)
20076 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20077 switch (this->Subtarget.getCPUDirective()) {
20100 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20104 EVT VT =
N->getValueType(0);
20109 APInt MulAmtAbs = MulAmt.
abs();
20111 if ((MulAmtAbs - 1).isPowerOf2()) {
20115 if (!IsProfitable(IsNeg,
true, VT))
20128 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20132 if (!IsProfitable(IsNeg,
false, VT))
20153 DAGCombinerInfo &DCI)
const {
20157 SDNodeFlags
Flags =
N->getFlags();
20158 EVT VT =
N->getValueType(0);
20159 SelectionDAG &DAG = DCI.DAG;
20160 unsigned Opc =
N->getOpcode();
20162 bool LegalOps = !DCI.isBeforeLegalizeOps();
20170 if (!
Flags.hasNoSignedZeros())
20186bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20188 if (!Subtarget.is64BitELFABI())
20198 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
20203 if (!Callee ||
Callee->isVarArg())
20216bool PPCTargetLowering::
20217isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20222 if (CI->getBitWidth() > 64)
20224 int64_t ConstVal = CI->getZExtValue();
20226 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20235PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20241 if ((Flags & FlagSet) == FlagSet)
20244 if ((Flags & FlagSet) == FlagSet)
20247 if ((Flags & FlagSet) == FlagSet)
20250 if ((Flags & FlagSet) == FlagSet)
20271 if ((FrameIndexAlign % 4) != 0)
20272 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20273 if ((FrameIndexAlign % 16) != 0)
20274 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20278 if ((FrameIndexAlign % 4) == 0)
20280 if ((FrameIndexAlign % 16) == 0)
20293 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
20294 if ((Imm & 0x3) == 0)
20296 if ((Imm & 0xf) == 0)
20302 const APInt &ConstImm = CN->getAPIntValue();
20321 const APInt &ConstImm = CN->getAPIntValue();
20331 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20342 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20351unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20356 if (!Subtarget.hasP9Vector())
20361 if (Subtarget.hasPrefixInstrs())
20364 if (Subtarget.hasSPE())
20373 unsigned ParentOp = Parent->
getOpcode();
20377 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
20378 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20390 if (LSB->isIndexed())
20396 assert(MN &&
"Parent should be a MemSDNode!");
20401 "Not expecting scalar integers larger than 16 bytes!");
20404 else if (
Size == 32)
20411 else if (
Size == 256) {
20412 assert(Subtarget.pairedVectorMemops() &&
20413 "256-bit vectors are only available when paired vector memops is "
20421 else if (MemVT == MVT::f128 || MemVT.
isVector())
20452 FlagSet &= ~PPC::MOF_NoExt;
20457 bool IsNonP1034BitConst =
20461 IsNonP1034BitConst)
20474 int16_t ForceXFormImm = 0;
20477 Disp =
N.getOperand(0);
20478 Base =
N.getOperand(1);
20489 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20490 Disp =
N.getOperand(0);
20491 Base =
N.getOperand(1);
20496 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20505 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
20511 if (PartVT == MVT::f64 &&
20512 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20521SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20525 EVT RetVT =
Op.getValueType();
20532 EVT ArgVT =
N.getValueType();
20536 Entry.IsZExt = !Entry.IsSExt;
20537 Args.push_back(Entry);
20545 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20558SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20559 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20561 if (
Op.getValueType() == MVT::f32)
20562 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20564 if (
Op.getValueType() == MVT::f64)
20565 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20570bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20571 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20572 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20576bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20577 return Op.getNode()->getFlags().hasApproximateFuncs();
20580bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20584SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20585 const char *LibCallFloatName,
20586 const char *LibCallDoubleNameFinite,
20587 const char *LibCallFloatNameFinite,
20590 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20593 if (!isLowringToMASSFiniteSafe(
Op))
20594 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20597 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20598 LibCallDoubleNameFinite,
Op, DAG);
20602 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20603 "__xl_powf_finite",
Op, DAG);
20607 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20608 "__xl_sinf_finite",
Op, DAG);
20612 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20613 "__xl_cosf_finite",
Op, DAG);
20617 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20618 "__xl_logf_finite",
Op, DAG);
20622 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20623 "__xl_log10f_finite",
Op, DAG);
20627 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20628 "__xl_expf_finite",
Op, DAG);
20653 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20664 assert(Subtarget.isUsingPCRelativeCalls() &&
20665 "Must be using PC-Relative calls when a valid PC-Relative node is "
20695 Disp =
N.getOperand(1).getOperand(0);
20700 Base =
N.getOperand(0);
20708 EVT CNType = CN->getValueType(0);
20709 uint64_t CNImm = CN->getZExtValue();
20720 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20722 int32_t Addr = (int32_t)CNImm;
20727 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20743 unsigned Opcode =
N.getOpcode();
20751 Base =
N.getOperand(0);
20770 Base = FI ?
N :
N.getOperand(1);
20771 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20782 bool IsVarArg)
const {
20792 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20829 return Intrinsic::ppc_atomicrmw_xchg_i128;
20831 return Intrinsic::ppc_atomicrmw_add_i128;
20833 return Intrinsic::ppc_atomicrmw_sub_i128;
20835 return Intrinsic::ppc_atomicrmw_and_i128;
20837 return Intrinsic::ppc_atomicrmw_or_i128;
20839 return Intrinsic::ppc_atomicrmw_xor_i128;
20841 return Intrinsic::ppc_atomicrmw_nand_i128;
20849 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20853 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20855 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20856 Value *LoHi = Builder.CreateIntrinsic(
20858 {AlignedAddr, IncrLo, IncrHi});
20859 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20860 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20861 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20862 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20863 return Builder.CreateOr(
20864 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20871 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20877 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20879 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20880 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20882 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20885 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20887 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20888 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20889 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20890 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20891 return Builder.CreateOr(
20892 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20896 return Subtarget.useCRBits();
20901bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
20912 DAGCombinerInfo &DCI)
const {
20917 EVT ResVT =
N->getValueType(0);
20919 EVT SrcVT = Src.getValueType();
20924 if (ResVT != MVT::i16 && ResVT != MVT::i8)
20927 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
20940 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
20941 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
20942 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
20944 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
20952 SmallVector<int, 16> BitIndices(16, 128);
20956 BitIndices[Idx] = EltSize * (NumElts - Idx) - 1;
20957 if (IsV8i8 && IsLE)
20958 BitIndices[Idx] += 64;
20961 std::reverse(BitIndices.begin(), BitIndices.end());
20963 for (
auto Idx : BitIndices)
20968 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
MachineInstr unsigned OpIdx
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static MachineBasicBlock * emitAtomicCmpSwapSoftware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit software-emulated atomic compare-and-swap for I8/I16 without hardware partword atomic support.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static void prepareOutOfLineGlueCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS)
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool IsSelectCC(unsigned Opcode)
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue combineXorSelectCC(SDNode *N, SelectionDAG &DAG)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left, SelectionDAG &DAG)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue combineSELECT_CCBitFloor(SDNode *N, SelectionDAG &DAG)
Optimize the bitfloor(X) pattern for PowerPC.
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static MachineBasicBlock * emitSelect(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit SELECT instruction, using ISEL if available, otherwise use branch-based control flow.
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static SDValue combineADDToSUB(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static bool canConvertSETCCToXori(SDNode *N)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static void createAtomicLoopBlocks(MachineFunction *F, MachineBasicBlock *BB, MachineBasicBlock *&loop1MBB, MachineBasicBlock *&loop2MBB, MachineBasicBlock *&exitMBB, MachineInstr &MI, MachineFunction::iterator It)
Helper function to create basic blocks for atomic compare-and-swap.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue combineZextSetccWithZero(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
static MachineBasicBlock * emitAtomicCmpSwapHardware(MachineInstr &MI, MachineBasicBlock *BB, const TargetInstrInfo *TII, const PPCSubtarget &Subtarget)
Emit hardware-supported atomic compare-and-swap for I32/I64 and I8/I16 with partword atomic support.
SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N, const SDLoc &DL)
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static void signExtendOperandIfUnknown(MachineInstr &MI, MachineBasicBlock *BB, unsigned OpIdx, bool IsByte, const PPCInstrInfo *TII)
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble()
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
const Constant * getConstVal() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
LLVM_ABI StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
LLVM_ABI bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
Tracks which library functions to use for a particular subtarget.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
bool use_empty(Register RegNo) const
use_empty - Return true if there are no instructions using the specified register.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
MCRegister getGlueCodeDescriptorRegister() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(const AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
void getTgtMemIntrinsic(SmallVectorImpl< IntrinsicInfo > &Infos, const CallBase &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getMachineOpcode() const
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
virtual bool isShuffleMaskLegal(ArrayRef< int >, EVT) const
Targets can use this to indicate that they only support some VECTOR_SHUFFLE operations,...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(const AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode, SDNodeFlags Flags={}) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::LibcallImpl LibcallImpl, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
virtual TargetLoweringObjectFile * getObjFileLowering() const
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
bool getFunctionSections() const
Return true if functions should be emitted into their own section, corresponding to -ffunction-sectio...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ INSERT_SUBVECTOR
INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2 inserted into VECTOR1.
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ AVGCEILS
AVGCEILS/AVGCEILU - Rounding averaging add - Add two integers using an integer of type i[N+2],...
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ SPLAT_VECTOR
SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL duplicated in all lanes.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo, const LibcallLoweringInfo *LibcallLowering)
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr RegState getDefRegState(bool B)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
@ Increment
Incrementally increasing token ID.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.