69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
108 "ppc-p10-store-forward",
113 "ppc-preinc",
cl::desc(
"enable preincrement load/store generation on PPC"),
118 cl::desc(
"Set the node scheduling preference to ILP on PPC"),
122 "ppc-unaligned",
cl::desc(
"enable unaligned load/store generation on PPC"),
130 "ppc-innermost-loop-align32",
139 cl::desc(
"enable vector permute decomposition"),
143 "ppc-auto-paired-vec-st",
144 cl::desc(
"enable automatically generated 32byte paired vector stores"),
149 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
153 cl::desc(
"Set minimum of largest number of comparisons to use bit test for "
158 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
162 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
163 "function to use initial-exec"));
168 "Number of shuffles lowered to a VPERM or XXPERM");
169STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
176 unsigned OpIdx,
bool IsByte,
194 initializeAddrModeMap();
197 bool isPPC64 = Subtarget.isPPC64();
199 const MVT RegVT = Subtarget.getScalarIntVT();
207 if (!Subtarget.hasEFPU2())
224 if (!Subtarget.hasP10Vector()) {
253 if (Subtarget.isISA3_0()) {
286 if (!Subtarget.hasSPE()) {
293 if (Subtarget.useCRBits()) {
296 if (isPPC64 || Subtarget.hasFPCVT()) {
362 if (Subtarget.isISA3_0()) {
397 if (!Subtarget.hasSPE()) {
402 if (Subtarget.hasVSX()) {
407 if (Subtarget.hasFSQRT()) {
412 if (Subtarget.hasFPRND()) {
453 if (Subtarget.hasSPE()) {
463 if (Subtarget.hasSPE())
467 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
470 if (!Subtarget.hasFSQRT() &&
471 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
474 if (Subtarget.hasFCPSGN()) {
482 if (Subtarget.hasFPRND()) {
496 if (Subtarget.isISA3_1()) {
502 ((Subtarget.hasP8Vector()) && isPPC64) ?
Custom
507 if (Subtarget.isISA3_0()) {
527 if (!Subtarget.useCRBits()) {
540 if (!Subtarget.useCRBits())
543 if (Subtarget.hasFPU()) {
554 if (!Subtarget.useCRBits())
559 if (Subtarget.hasSPE()) {
591 if (Subtarget.hasDirectMove() && isPPC64) {
655 if (Subtarget.is64BitELFABI()) {
666 }
else if (Subtarget.is32BitELFABI()) {
674 if (Subtarget.is32BitELFABI())
690 if (Subtarget.isISA3_0() && isPPC64) {
718 if (Subtarget.hasSPE()) {
740 if (Subtarget.has64BitSupport()) {
755 if (Subtarget.hasLFIWAX() || isPPC64) {
761 if (Subtarget.hasSPE()) {
771 if (Subtarget.hasFPCVT()) {
772 if (Subtarget.has64BitSupport()) {
793 if (Subtarget.use64BitRegs()) {
811 if (Subtarget.has64BitSupport()) {
818 if (Subtarget.hasVSX()) {
831 if (Subtarget.hasAltivec()) {
832 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
849 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
862 if (Subtarget.hasVSX()) {
871 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
881 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
955 if (!Subtarget.hasP8Vector()) {
997 if (Subtarget.hasAltivec())
998 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
1001 if (Subtarget.hasP8Altivec())
1012 if (Subtarget.hasVSX()) {
1018 if (Subtarget.hasP8Altivec())
1023 if (Subtarget.isISA3_1()) {
1069 if (Subtarget.hasVSX()) {
1072 if (Subtarget.hasP8Vector()) {
1076 if (Subtarget.hasDirectMove() && isPPC64) {
1125 if (Subtarget.hasP8Vector())
1134 if (Subtarget.hasP8Altivec()) {
1161 if (Subtarget.isISA3_1())
1264 if (Subtarget.hasP8Altivec()) {
1269 if (Subtarget.hasP9Vector()) {
1274 if (Subtarget.useCRBits()) {
1334 }
else if (Subtarget.hasVSX()) {
1359 for (
MVT VT : {MVT::f32, MVT::f64}) {
1378 if (Subtarget.hasP9Altivec()) {
1379 if (Subtarget.isISA3_1()) {
1402 if (Subtarget.hasP10Vector()) {
1417 if (Subtarget.pairedVectorMemops()) {
1422 if (Subtarget.hasMMA()) {
1423 if (Subtarget.isISAFuture()) {
1439 if (Subtarget.has64BitSupport())
1442 if (Subtarget.isISA3_1())
1460 if (Subtarget.hasAltivec()) {
1478 if (Subtarget.hasFPCVT())
1481 if (Subtarget.useCRBits())
1490 if (Subtarget.useCRBits()) {
1494 if (Subtarget.hasP8Vector())
1499 if (Subtarget.useCRBits()) {
1515 auto CPUDirective = Subtarget.getCPUDirective();
1516 switch (CPUDirective) {
1539 if (Subtarget.enableMachineScheduler())
1613void PPCTargetLowering::initializeAddrModeMap() {
1664 if (MaxAlign == MaxMaxAlign)
1667 if (MaxMaxAlign >= 32 &&
1668 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1669 MaxAlign =
Align(32);
1670 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1672 MaxAlign =
Align(16);
1676 if (EltAlign > MaxAlign)
1677 MaxAlign = EltAlign;
1679 for (
auto *EltTy : STy->elements()) {
1682 if (EltAlign > MaxAlign)
1683 MaxAlign = EltAlign;
1684 if (MaxAlign == MaxMaxAlign)
1697 if (Subtarget.hasAltivec())
1703 return Subtarget.useSoftFloat();
1707 return Subtarget.hasSPE();
1715 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1716 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1720 if (VTy->getScalarType()->isIntegerTy()) {
1722 if (ElemSizeInBits == 32) {
1723 Index = Subtarget.isLittleEndian() ? 2 : 1;
1726 if (ElemSizeInBits == 64) {
1727 Index = Subtarget.isLittleEndian() ? 1 : 0;
1738 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1755 return CFP->getValueAPF().isZero();
1760 return CFP->getValueAPF().isZero();
1768 return Op < 0 ||
Op == Val;
1780 if (ShuffleKind == 0) {
1783 for (
unsigned i = 0; i != 16; ++i)
1786 }
else if (ShuffleKind == 2) {
1789 for (
unsigned i = 0; i != 16; ++i)
1792 }
else if (ShuffleKind == 1) {
1793 unsigned j = IsLE ? 0 : 1;
1794 for (
unsigned i = 0; i != 8; ++i)
1811 if (ShuffleKind == 0) {
1814 for (
unsigned i = 0; i != 16; i += 2)
1818 }
else if (ShuffleKind == 2) {
1821 for (
unsigned i = 0; i != 16; i += 2)
1825 }
else if (ShuffleKind == 1) {
1826 unsigned j = IsLE ? 0 : 2;
1827 for (
unsigned i = 0; i != 8; i += 2)
1848 if (!Subtarget.hasP8Vector())
1852 if (ShuffleKind == 0) {
1855 for (
unsigned i = 0; i != 16; i += 4)
1861 }
else if (ShuffleKind == 2) {
1864 for (
unsigned i = 0; i != 16; i += 4)
1870 }
else if (ShuffleKind == 1) {
1871 unsigned j = IsLE ? 0 : 4;
1872 for (
unsigned i = 0; i != 8; i += 4)
1889 unsigned LHSStart,
unsigned RHSStart) {
1890 if (
N->getValueType(0) != MVT::v16i8)
1892 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
1893 "Unsupported merge size!");
1895 for (
unsigned i = 0; i != 8/UnitSize; ++i)
1896 for (
unsigned j = 0; j != UnitSize; ++j) {
1898 LHSStart+j+i*UnitSize) ||
1900 RHSStart+j+i*UnitSize))
1915 if (ShuffleKind == 1)
1917 else if (ShuffleKind == 2)
1922 if (ShuffleKind == 1)
1924 else if (ShuffleKind == 0)
1940 if (ShuffleKind == 1)
1942 else if (ShuffleKind == 2)
1947 if (ShuffleKind == 1)
1949 else if (ShuffleKind == 0)
1999 unsigned RHSStartValue) {
2000 if (
N->getValueType(0) != MVT::v16i8)
2003 for (
unsigned i = 0; i < 2; ++i)
2004 for (
unsigned j = 0; j < 4; ++j)
2006 i*RHSStartValue+j+IndexOffset) ||
2008 i*RHSStartValue+j+IndexOffset+8))
2030 unsigned indexOffset = CheckEven ? 4 : 0;
2031 if (ShuffleKind == 1)
2033 else if (ShuffleKind == 2)
2039 unsigned indexOffset = CheckEven ? 0 : 4;
2040 if (ShuffleKind == 1)
2042 else if (ShuffleKind == 0)
2058 if (
N->getValueType(0) != MVT::v16i8)
2065 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2068 if (i == 16)
return -1;
2073 if (ShiftAmt < i)
return -1;
2078 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2080 for (++i; i != 16; ++i)
2083 }
else if (ShuffleKind == 1) {
2085 for (++i; i != 16; ++i)
2092 ShiftAmt = 16 - ShiftAmt;
2101 EVT VT =
N->getValueType(0);
2102 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2103 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2106 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2110 if (
N->getMaskElt(0) % EltSize != 0)
2115 unsigned ElementBase =
N->getMaskElt(0);
2118 if (ElementBase >= 16)
2123 for (
unsigned i = 1; i != EltSize; ++i)
2124 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2127 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2129 if (
N->getMaskElt(i) < 0) {
2130 for (
unsigned j = 1; j != EltSize; ++j)
2131 if (
N->getMaskElt(i + j) >= 0)
2134 for (
unsigned j = 0; j != EltSize; ++j)
2135 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2152 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2153 "Unexpected element width.");
2154 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2156 unsigned NumOfElem = 16 / Width;
2157 unsigned MaskVal[16];
2158 for (
unsigned i = 0; i < NumOfElem; ++i) {
2159 MaskVal[0] =
N->getMaskElt(i * Width);
2160 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2162 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2166 for (
unsigned int j = 1; j < Width; ++j) {
2167 MaskVal[j] =
N->getMaskElt(i * Width + j);
2168 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2178 unsigned &InsertAtByte,
bool &
Swap,
bool IsLE) {
2183 unsigned M0 =
N->getMaskElt(0) / 4;
2184 unsigned M1 =
N->getMaskElt(4) / 4;
2185 unsigned M2 =
N->getMaskElt(8) / 4;
2186 unsigned M3 =
N->getMaskElt(12) / 4;
2187 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2188 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2193 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2194 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2195 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2196 InsertAtByte = IsLE ? 12 : 0;
2201 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2202 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2203 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2204 InsertAtByte = IsLE ? 8 : 4;
2209 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2210 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2211 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2212 InsertAtByte = IsLE ? 4 : 8;
2217 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2218 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2219 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2220 InsertAtByte = IsLE ? 0 : 12;
2227 if (
N->getOperand(1).isUndef()) {
2230 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2231 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2232 InsertAtByte = IsLE ? 12 : 0;
2235 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2236 InsertAtByte = IsLE ? 8 : 4;
2239 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2240 InsertAtByte = IsLE ? 4 : 8;
2243 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2244 InsertAtByte = IsLE ? 0 : 12;
2253 bool &
Swap,
bool IsLE) {
2254 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2260 unsigned M0 =
N->getMaskElt(0) / 4;
2261 unsigned M1 =
N->getMaskElt(4) / 4;
2262 unsigned M2 =
N->getMaskElt(8) / 4;
2263 unsigned M3 =
N->getMaskElt(12) / 4;
2267 if (
N->getOperand(1).isUndef()) {
2268 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2269 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2272 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2278 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2282 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2287 ShiftElts = (8 -
M0) % 8;
2288 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2293 ShiftElts = (4 -
M0) % 4;
2298 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2303 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2315 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2320 for (
int i = 0; i < 16; i += Width)
2321 if (
N->getMaskElt(i) != i + Width - 1)
2352 bool &
Swap,
bool IsLE) {
2353 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2359 unsigned M0 =
N->getMaskElt(0) / 8;
2360 unsigned M1 =
N->getMaskElt(8) / 8;
2361 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2365 if (
N->getOperand(1).isUndef()) {
2366 if ((
M0 |
M1) < 2) {
2367 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2375 if (
M0 > 1 &&
M1 < 2) {
2385 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2390 }
else if (
M0 > 1 &&
M1 < 2) {
2398 DM = (
M0 << 1) + (
M1 & 1);
2413 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2418 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2434 unsigned EltSize = 16/
N->getNumOperands();
2435 if (EltSize < ByteSize) {
2436 unsigned Multiple = ByteSize/EltSize;
2438 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2441 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2442 if (
N->getOperand(i).isUndef())
continue;
2446 if (!UniquedVals[i&(Multiple-1)].
getNode())
2447 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2448 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2458 bool LeadingZero =
true;
2459 bool LeadingOnes =
true;
2460 for (
unsigned i = 0; i != Multiple-1; ++i) {
2461 if (!UniquedVals[i].
getNode())
continue;
2468 if (!UniquedVals[Multiple-1].
getNode())
2475 if (!UniquedVals[Multiple-1].
getNode())
2486 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2487 if (
N->getOperand(i).isUndef())
continue;
2489 OpVal =
N->getOperand(i);
2490 else if (OpVal !=
N->getOperand(i))
2496 unsigned ValSizeInBytes = EltSize;
2499 Value = CN->getZExtValue();
2501 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2508 if (ValSizeInBytes < ByteSize)
return SDValue();
2519 if (MaskVal == 0)
return SDValue();
2539 Imm = (int16_t)
N->getAsZExtVal();
2540 if (
N->getValueType(0) == MVT::i32)
2541 return Imm == (int32_t)
N->getAsZExtVal();
2543 return Imm == (int64_t)
N->getAsZExtVal();
2561 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2569 for (
SDNode *U :
N->users()) {
2571 if (Memop->getMemoryVT() == MVT::f64) {
2572 Base =
N.getOperand(0);
2573 Index =
N.getOperand(1);
2616 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2618 if (
N.getOperand(1).getOpcode() == PPCISD::Lo)
2621 Base =
N.getOperand(0);
2622 Index =
N.getOperand(1);
2624 }
else if (
N.getOpcode() ==
ISD::OR) {
2626 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm)))
2638 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2639 Base =
N.getOperand(0);
2640 Index =
N.getOperand(1);
2710 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2716 Base =
N.getOperand(0);
2719 }
else if (
N.getOperand(1).getOpcode() == PPCISD::Lo) {
2721 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2722 "Cannot handle constant offsets yet!");
2723 Disp =
N.getOperand(1).getOperand(0);
2728 Base =
N.getOperand(0);
2731 }
else if (
N.getOpcode() ==
ISD::OR) {
2734 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2748 Base =
N.getOperand(0);
2761 (!EncodingAlignment ||
isAligned(*EncodingAlignment,
Imm))) {
2764 CN->getValueType(0));
2769 if ((CN->getValueType(0) == MVT::i32 ||
2770 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2771 (!EncodingAlignment ||
2772 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2773 int Addr = (int)CN->getZExtValue();
2780 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2801 if (
N.getValueType() != MVT::i64)
2814 Base =
N.getOperand(0);
2830 Base =
N.getOperand(0);
2863 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2864 Base =
N.getOperand(0);
2865 Index =
N.getOperand(1);
2887 if (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR)
2908 EVT MemVT = LD->getMemoryVT();
2915 if (!ST.hasP8Vector())
2920 if (!ST.hasP9Vector())
2932 if (
Use.getResNo() == 0 &&
2934 Use.
getUser()->getOpcode() != PPCISD::SCALAR_TO_VECTOR_PERMUTED)
2955 Ptr = LD->getBasePtr();
2956 VT = LD->getMemoryVT();
2957 Alignment = LD->getAlign();
2959 Ptr = ST->getBasePtr();
2960 VT = ST->getMemoryVT();
2961 Alignment = ST->getAlign();
3000 if (VT != MVT::i64) {
3005 if (Alignment <
Align(4))
3015 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3032 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3074 EVT VT = Subtarget.getScalarIntVT();
3076 : Subtarget.isAIXABI()
3079 SDValue
Ops[] = { GA,
Reg };
3081 PPCISD::TOC_ENTRY, dl, DAG.
getVTList(VT, MVT::Other),
Ops, VT,
3088 EVT PtrVT =
Op.getValueType();
3094 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3095 if (Subtarget.isUsingPCRelativeCalls()) {
3100 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, ConstPool);
3104 return getTOCEntry(DAG, SDLoc(CP), GA);
3107 unsigned MOHiFlag, MOLoFlag;
3111 if (IsPIC && Subtarget.isSVR4ABI()) {
3114 return getTOCEntry(DAG, SDLoc(CP), GA);
3137 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3144 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3161 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3174 EVT PtrVT =
Op.getValueType();
3192 return getTOCEntry(DAG,
SDLoc(JT), GA);
3195 unsigned MOHiFlag, MOLoFlag;
3199 if (IsPIC && Subtarget.isSVR4ABI()) {
3202 return getTOCEntry(DAG, SDLoc(GA), GA);
3212 EVT PtrVT =
Op.getValueType();
3217 if (Subtarget.isUsingPCRelativeCalls()) {
3222 SDValue MatAddr = DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3228 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3231 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3240 unsigned MOHiFlag, MOLoFlag;
3250 if (Subtarget.isAIXABI())
3251 return LowerGlobalTLSAddressAIX(
Op, DAG);
3253 return LowerGlobalTLSAddressLinux(
Op, DAG);
3275 if (
I.getOpcode() == Instruction::Call)
3277 if (
Function *CF = CI->getCalledFunction())
3278 if (CF->isDeclaration() &&
3279 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3287 unsigned TLSGVCnt = TLSGV.
size();
3297 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3310 const GlobalValue *GV = GA->
getGlobal();
3312 bool Is64Bit = Subtarget.isPPC64();
3316 if (Subtarget.hasAIXShLibTLSModelOpt())
3326 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3327 bool HasAIXSmallTLSGlobalAttr =
false;
3328 SDValue VariableOffsetTGA =
3330 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3334 if (GVar->hasAttribute(
"aix-small-tls"))
3335 HasAIXSmallTLSGlobalAttr =
true;
3354 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3355 IsTLSLocalExecModel) {
3360 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA, TLSReg);
3370 TLSReg = DAG.
getNode(PPCISD::GET_TPOINTER, dl, PtrVT);
3375 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3377 "currently only supported on AIX (64-bit mode).");
3379 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, VariableOffset);
3383 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3387 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3389 "currently only supported on AIX (64-bit mode).");
3395 SDValue VariableOffsetTGA =
3397 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3400 GlobalVariable *TLSGV =
3404 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3405 SDValue ModuleHandleTGA =
3407 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3408 SDValue ModuleHandle =
3409 DAG.
getNode(PPCISD::TLSLD_AIX, dl, PtrVT, ModuleHandleTOC);
3418 if (HasAIXSmallLocalDynamicTLS) {
3423 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, VariableOffsetTGA,
3427 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3436 SDValue VariableOffsetTGA =
3438 SDValue RegionHandleTGA =
3440 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3441 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3442 return DAG.
getNode(PPCISD::TLSGD_AIX, dl, PtrVT, VariableOffset,
3457 const GlobalValue *GV = GA->
getGlobal();
3459 bool is64bit = Subtarget.isPPC64();
3467 if (Subtarget.isUsingPCRelativeCalls()) {
3468 SDValue TLSReg = DAG.
getRegister(PPC::X13, MVT::i64);
3472 DAG.
getNode(PPCISD::TLS_LOCAL_EXEC_MAT_ADDR, dl, PtrVT, TGA);
3473 return DAG.
getNode(PPCISD::ADD_TLS, dl, PtrVT, TLSReg, MatAddr);
3480 SDValue TLSReg = is64bit ? DAG.
getRegister(PPC::X13, MVT::i64)
3483 SDValue
Hi = DAG.
getNode(PPCISD::Hi, dl, PtrVT, TGAHi, TLSReg);
3484 return DAG.
getNode(PPCISD::Lo, dl, PtrVT, TGALo,
Hi);
3488 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3495 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR, dl, PtrVT, TGA);
3497 MachinePointerInfo());
3502 SDValue GOTReg = DAG.
getRegister(PPC::X2, MVT::i64);
3504 DAG.
getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl, PtrVT, GOTReg, TGA);
3506 if (!TM.isPositionIndependent())
3507 GOTPtr = DAG.
getNode(PPCISD::PPC32_GOT, dl, PtrVT);
3513 TPOffset = DAG.
getNode(PPCISD::LD_GOT_TPREL_L, dl, PtrVT, TGA, GOTPtr);
3519 if (Subtarget.isUsingPCRelativeCalls()) {
3522 return DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3529 SDValue GOTReg = DAG.
getRegister(PPC::X2, MVT::i64);
3530 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSGD_HA, dl, PtrVT,
3538 return DAG.
getNode(PPCISD::ADDI_TLSGD_L_ADDR, dl, PtrVT,
3543 if (Subtarget.isUsingPCRelativeCalls()) {
3547 DAG.
getNode(PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR, dl, PtrVT, TGA);
3548 return DAG.
getNode(PPCISD::PADDI_DTPREL, dl, PtrVT, MatPCRel, TGA);
3555 SDValue GOTReg = DAG.
getRegister(PPC::X2, MVT::i64);
3556 GOTPtr = DAG.
getNode(PPCISD::ADDIS_TLSLD_HA, dl, PtrVT,
3564 SDValue TLSAddr = DAG.
getNode(PPCISD::ADDI_TLSLD_L_ADDR, dl,
3565 PtrVT, GOTPtr, TGA, TGA);
3566 SDValue DtvOffsetHi = DAG.
getNode(PPCISD::ADDIS_DTPREL_HA, dl,
3567 PtrVT, TLSAddr, TGA);
3568 return DAG.
getNode(PPCISD::ADDI_DTPREL_L, dl, PtrVT, DtvOffsetHi, TGA);
3576 EVT PtrVT =
Op.getValueType();
3579 const GlobalValue *GV = GSDN->
getGlobal();
3583 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3584 if (Subtarget.isUsingPCRelativeCalls()) {
3589 SDValue MatPCRel = DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3591 MachinePointerInfo());
3596 return DAG.
getNode(PPCISD::MAT_PCREL_ADDR,
DL, Ty, GA);
3601 return getTOCEntry(DAG,
DL, GA);
3604 unsigned MOHiFlag, MOLoFlag;
3608 if (IsPIC && Subtarget.isSVR4ABI()) {
3612 return getTOCEntry(DAG,
DL, GA);
3624 bool IsStrict =
Op->isStrictFPOpcode();
3625 const SDNodeFlags
Flags =
Op.getNode()->getFlags();
3628 SDValue
LHS =
Op.getOperand(IsStrict ? 1 : 0);
3629 SDValue
RHS =
Op.getOperand(IsStrict ? 2 : 1);
3630 SDValue Chain = IsStrict ?
Op.getOperand(0) : SDValue();
3631 EVT LHSVT =
LHS.getValueType();
3635 if (LHSVT == MVT::f128 ||
3636 (Subtarget.hasSPE() && (LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
3637 (!
Flags.hasNoNaNs() || !
Flags.hasNoInfs()))) {
3638 assert(!Subtarget.hasP9Vector() &&
3639 "SETCC for f128 is already legal under Power9!");
3648 }
else if (LHSVT == MVT::f32 || LHSVT == MVT::f64) {
3652 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3654 if (
Op.getValueType() == MVT::v2i64) {
3657 if (
LHS.getValueType() == MVT::v2i64) {
3665 int ShuffV[] = {1, 0, 3, 2};
3670 dl, MVT::v4i32, Shuff, SetCC32));
3687 if (
C->isAllOnes() ||
C->isZero())
3697 EVT VT =
Op.getValueType();
3705 const SDNodeFlags
Flags =
Op->getFlags();
3706 SDValue Chain =
Op.getOperand(0);
3708 SDValue
LHS =
Op.getOperand(2);
3709 SDValue
RHS =
Op.getOperand(3);
3710 SDValue Dest =
Op.getOperand(4);
3711 EVT LHSVT =
LHS.getValueType();
3714 assert(Subtarget.hasSPE() &&
"LowerBR_CC used only for targets with SPE");
3716 if ((LHSVT == MVT::f32 || LHSVT == MVT::f64) &&
Flags.hasNoNaNs() &&
3734 SDNode *
Node =
Op.getNode();
3735 EVT VT =
Node->getValueType(0);
3737 SDValue InChain =
Node->getOperand(0);
3738 SDValue VAListPtr =
Node->getOperand(1);
3742 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3746 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3749 if (VT == MVT::i64) {
3753 SDValue CC64 = DAG.
getSetCC(dl, MVT::i32, GprAnd,
3755 SDValue GprIndexPlusOne = DAG.
getNode(
ISD::ADD, dl, MVT::i32, GprIndex,
3768 FprPtr, MachinePointerInfo(SV), MVT::i8);
3778 SDValue OverflowArea =
3779 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3780 InChain = OverflowArea.
getValue(1);
3782 SDValue RegSaveArea =
3783 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3813 MachinePointerInfo(SV), MVT::i8);
3819 SDValue OverflowAreaPlusN = DAG.
getNode(
ISD::ADD, dl, PtrVT, OverflowArea,
3826 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3827 MachinePointerInfo(), MVT::i32);
3829 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3833 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3839 Align(8),
false,
true,
nullptr, std::nullopt,
3840 MachinePointerInfo(), MachinePointerInfo());
3845 return Op.getOperand(0);
3850 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3854 "Expecting Inline ASM node.");
3864 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3869 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3870 unsigned NumVals =
Flags.getNumOperandRegisters();
3873 switch (
Flags.getKind()) {
3884 for (; NumVals; --NumVals, ++i) {
3886 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3901 SDValue Chain =
Op.getOperand(0);
3902 SDValue Trmp =
Op.getOperand(1);
3903 SDValue FPtr =
Op.getOperand(2);
3904 SDValue Nest =
Op.getOperand(3);
3909 if (Subtarget.isAIXABI()) {
3914 MaybeAlign PointerAlign(PointerSize);
3915 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3918 : MachineMemOperand::MONone;
3922 SDValue SDTOCPtrOffset = DAG.
getConstant(TOCPointerOffset, dl, PtrVT);
3923 SDValue SDEnvPtrOffset = DAG.
getConstant(EnvPointerOffset, dl, PtrVT);
3925 const Value *TrampolineAddr =
3930 SDValue OutChains[3];
3934 SDValue LoadEntryPoint =
3935 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
3936 PointerAlign, MMOFlags);
3937 SDValue EPLoadChain = LoadEntryPoint.
getValue(1);
3938 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
3939 MachinePointerInfo(TrampolineAddr, 0));
3943 SDValue TOCFromDescriptorPtr =
3945 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
3946 MachinePointerInfo(Func, TOCPointerOffset),
3947 PointerAlign, MMOFlags);
3948 SDValue TrampolineTOCPointer =
3950 SDValue TOCLoadChain = TOCReg.
getValue(1);
3952 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
3953 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
3957 SDValue EnvPointer = DAG.
getNode(
ISD::ADD, dl, PtrVT, Trmp, SDEnvPtrOffset);
3959 DAG.
getStore(Chain, dl, Nest, EnvPointer,
3960 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
3967 bool isPPC64 = (PtrVT == MVT::i64);
3974 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
3980 TargetLowering::CallLoweringInfo CLI(DAG);
3981 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3985 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3986 return CallResult.second;
3991 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
3996 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
4001 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4002 MachinePointerInfo(SV));
4036 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4037 SDValue ConstFrameOffset = DAG.
getConstant(FrameOffset, dl, PtrVT);
4039 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4040 SDValue ConstStackOffset = DAG.
getConstant(StackOffset, dl, PtrVT);
4043 SDValue ConstFPROffset = DAG.
getConstant(FPROffset, dl, PtrVT);
4048 SDValue firstStore =
4050 MachinePointerInfo(SV), MVT::i8);
4056 SDValue secondStore =
4058 MachinePointerInfo(SV, nextOffset), MVT::i8);
4059 nextOffset += StackOffset;
4060 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4063 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4064 MachinePointerInfo(SV, nextOffset));
4065 nextOffset += FrameOffset;
4066 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4069 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4070 MachinePointerInfo(SV, nextOffset));
4075static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4076 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4077 PPC::F11, PPC::F12, PPC::F13};
4082 unsigned PtrByteSize) {
4084 if (Flags.isByVal())
4085 ArgSize = Flags.getByValSize();
4089 if (!Flags.isInConsecutiveRegs())
4090 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4099 unsigned PtrByteSize) {
4100 Align Alignment(PtrByteSize);
4103 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4104 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4105 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4106 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4107 Alignment =
Align(16);
4110 if (Flags.isByVal()) {
4111 auto BVAlign = Flags.getNonZeroByValAlign();
4112 if (BVAlign > PtrByteSize) {
4113 if (BVAlign.value() % PtrByteSize != 0)
4115 "ByVal alignment is not a multiple of the pointer size");
4117 Alignment = BVAlign;
4122 if (Flags.isInConsecutiveRegs()) {
4126 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4140 unsigned PtrByteSize,
unsigned LinkageSize,
4141 unsigned ParamAreaSize,
unsigned &ArgOffset,
4142 unsigned &AvailableFPRs,
4143 unsigned &AvailableVRs) {
4144 bool UseMemory =
false;
4149 ArgOffset =
alignTo(ArgOffset, Alignment);
4152 if (ArgOffset >= LinkageSize + ParamAreaSize)
4157 if (Flags.isInConsecutiveRegsLast())
4158 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4161 if (ArgOffset > LinkageSize + ParamAreaSize)
4166 if (!Flags.isByVal()) {
4167 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4168 if (AvailableFPRs > 0) {
4172 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4173 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4174 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4175 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4176 if (AvailableVRs > 0) {
4188 unsigned NumBytes) {
4192SDValue PPCTargetLowering::LowerFormalArguments(
4196 if (Subtarget.isAIXABI())
4197 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4199 if (Subtarget.is64BitELFABI())
4200 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4202 assert(Subtarget.is32BitELFABI());
4203 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4207SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4243 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4249 const Align PtrAlign(4);
4257 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4258 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4261 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4262 CCValAssign &VA = ArgLocs[i];
4274 RC = &PPC::GPRCRegClass;
4277 if (Subtarget.hasP8Vector())
4278 RC = &PPC::VSSRCRegClass;
4279 else if (Subtarget.hasSPE())
4280 RC = &PPC::GPRCRegClass;
4282 RC = &PPC::F4RCRegClass;
4285 if (Subtarget.hasVSX())
4286 RC = &PPC::VSFRCRegClass;
4287 else if (Subtarget.hasSPE())
4289 RC = &PPC::GPRCRegClass;
4291 RC = &PPC::F8RCRegClass;
4300 RC = &PPC::VRRCRegClass;
4307 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4308 assert(i + 1 < e &&
"No second half of double precision argument");
4311 SDValue ArgValueLo = DAG.
getCopyFromReg(Chain, dl, RegLo, MVT::i32);
4312 SDValue ArgValueHi = DAG.
getCopyFromReg(Chain, dl, RegHi, MVT::i32);
4313 if (!Subtarget.isLittleEndian())
4315 ArgValue = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64, ArgValueLo,
4320 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4321 if (ValVT == MVT::i1)
4336 ArgOffset += ArgSize - ObjSize;
4354 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4359 unsigned MinReservedArea = CCByValInfo.getStackSize();
4360 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4376 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4377 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4379 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4382 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4385 unsigned NumFPArgRegs = std::size(FPArgRegs);
4394 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4395 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4398 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4411 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4418 SDValue PtrOff = DAG.
getConstant(PtrVT.getSizeInBits()/8, dl, PtrVT);
4426 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4430 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4437 SDValue PtrOff = DAG.
getConstant(MVT(MVT::f64).getSizeInBits()/8, dl,
4443 if (!MemOps.
empty())
4454 const SDLoc &dl)
const {
4458 else if (
Flags.isZExt())
4465SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4471 bool isELFv2ABI = Subtarget.isELFv2ABI();
4472 bool isLittleEndian = Subtarget.isLittleEndian();
4475 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4478 "fastcc not supported on varargs functions");
4484 unsigned PtrByteSize = 8;
4485 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4488 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4489 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4492 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4493 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4496 const unsigned Num_GPR_Regs = std::size(GPR);
4498 const unsigned Num_VR_Regs = std::size(VR);
4506 bool HasParameterArea = !isELFv2ABI || isVarArg;
4507 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4508 unsigned NumBytes = LinkageSize;
4509 unsigned AvailableFPRs = Num_FPR_Regs;
4510 unsigned AvailableVRs = Num_VR_Regs;
4511 for (
const ISD::InputArg &In : Ins) {
4512 if (
In.Flags.isNest())
4516 LinkageSize, ParamAreaSize, NumBytes,
4517 AvailableFPRs, AvailableVRs))
4518 HasParameterArea =
true;
4525 unsigned ArgOffset = LinkageSize;
4526 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4529 unsigned CurArgIdx = 0;
4530 for (
unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) {
4532 bool needsLoad =
false;
4533 EVT ObjectVT = Ins[ArgNo].VT;
4534 EVT OrigVT = Ins[ArgNo].ArgVT;
4536 unsigned ArgSize = ObjSize;
4537 ISD::ArgFlagsTy
Flags = Ins[ArgNo].Flags;
4538 if (Ins[ArgNo].isOrigArg()) {
4539 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4540 CurArgIdx = Ins[ArgNo].getOrigArgIndex();
4545 unsigned CurArgOffset;
4547 auto ComputeArgOffset = [&]() {
4551 ArgOffset =
alignTo(ArgOffset, Alignment);
4552 CurArgOffset = ArgOffset;
4559 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4560 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4565 if (
Flags.isByVal()) {
4566 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4572 ObjSize =
Flags.getByValSize();
4573 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4595 if (HasParameterArea ||
4596 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4603 if (ObjSize < PtrByteSize) {
4607 if (!isLittleEndian) {
4608 SDValue ArgOff = DAG.
getConstant(PtrByteSize - ObjSize, dl, PtrVT);
4613 if (GPR_idx != Num_GPR_Regs) {
4620 MachinePointerInfo(&*FuncArg), ObjType);
4625 ArgOffset += PtrByteSize;
4634 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4635 if (GPR_idx == Num_GPR_Regs)
4646 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4650 MachinePointerInfo(&*FuncArg, j), ObjType);
4654 ArgOffset += ArgSize;
4663 if (
Flags.isNest()) {
4668 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4669 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4677 if (GPR_idx != Num_GPR_Regs) {
4682 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4685 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4691 ArgSize = PtrByteSize;
4702 if (FPR_idx != Num_FPR_Regs) {
4705 if (ObjectVT == MVT::f32)
4707 Subtarget.hasP8Vector()
4708 ? &PPC::VSSRCRegClass
4709 : &PPC::F4RCRegClass);
4712 ? &PPC::VSFRCRegClass
4713 : &PPC::F8RCRegClass);
4728 if (ObjectVT == MVT::f32) {
4729 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4747 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4748 ArgOffset += ArgSize;
4749 if (
Flags.isInConsecutiveRegsLast())
4750 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4764 if (VR_idx != Num_VR_Regs) {
4781 if (ObjSize < ArgSize && !isLittleEndian)
4782 CurArgOffset += ArgSize - ObjSize;
4785 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4792 unsigned MinReservedArea;
4793 if (HasParameterArea)
4794 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4796 MinReservedArea = LinkageSize;
4813 int Depth = ArgOffset;
4822 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4823 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4830 SDValue PtrOff = DAG.
getConstant(PtrByteSize, dl, PtrVT);
4835 if (!MemOps.
empty())
4844 unsigned ParamSize) {
4846 if (!isTailCall)
return 0;
4850 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4852 if (SPDiff < FI->getTailCallSPDelta())
4868 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4927 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4930 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4942 const unsigned PtrByteSize = 8;
4946 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4947 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4950 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4951 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4954 const unsigned NumGPRs = std::size(GPR);
4955 const unsigned NumFPRs = 13;
4956 const unsigned NumVRs = std::size(VR);
4957 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4959 unsigned NumBytes = LinkageSize;
4960 unsigned AvailableFPRs = NumFPRs;
4961 unsigned AvailableVRs = NumVRs;
4964 if (Param.Flags.isNest())
continue;
4967 LinkageSize, ParamAreaSize, NumBytes,
4968 AvailableFPRs, AvailableVRs))
4979 auto CalleeArgEnd = CB.
arg_end();
4982 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4983 const Value* CalleeArg = *CalleeArgIter;
4984 const Value* CallerArg = &(*CallerArgIter);
4985 if (CalleeArg == CallerArg)
5011 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5021bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5026 bool isCalleeExternalSymbol)
const {
5033 if (isVarArg)
return false;
5040 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5076 if (!Subtarget.isUsingPCRelativeCalls() &&
5081 if (!Subtarget.isUsingPCRelativeCalls() &&
5110bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5123 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5144 if (!
C)
return nullptr;
5146 int Addr =
C->getZExtValue();
5147 if ((Addr & 3) != 0 ||
5153 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5160struct TailCallArgumentInfo {
5165 TailCallArgumentInfo() =
default;
5175 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5176 SDValue Arg = TailCallArgs[i].Arg;
5177 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5178 int FI = TailCallArgs[i].FrameIdx;
5181 Chain, dl, Arg, FIN,
5190 int SPDiff,
const SDLoc &dl) {
5196 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5197 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5199 NewRetAddrLoc,
true);
5202 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5212 int SPDiff,
unsigned ArgOffset,
5214 int Offset = ArgOffset + SPDiff;
5217 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5219 TailCallArgumentInfo Info;
5221 Info.FrameIdxOp = FIN;
5229SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5234 LROpOut = getReturnAddrFrameIndex(DAG);
5235 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5236 MachinePointerInfo());
5237 Chain = SDValue(LROpOut.
getNode(), 1);
5252 Align Alignment = Flags.getNonZeroByValAlign();
5254 Chain, dl, Dst, Src, SizeNode, Alignment, Alignment,
false,
false,
5262 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5286 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5296 if (!MemOpChains2.
empty())
5320SDValue PPCTargetLowering::LowerCallResult(
5328 CCRetInfo.AnalyzeCallResult(
5334 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5335 CCValAssign &VA = RVLocs[i];
5340 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5350 if (!Subtarget.isLittleEndian())
5352 Val = DAG.
getNode(PPCISD::BUILD_SPE64, dl, MVT::f64,
Lo,
Hi);
5418 bool IsStrictFPCall =
false) {
5420 return PPCISD::TC_RETURN;
5422 unsigned RetOpc = 0;
5433 if (Subtarget.usePointerGlueHelper())
5434 RetOpc = PPCISD::BL_LOAD_TOC;
5440 RetOpc = PPCISD::CALL_NOTOC;
5455 RetOpc = PPCISD::CALL;
5456 if (IsStrictFPCall) {
5460 case PPCISD::BCTRL_LOAD_TOC:
5461 RetOpc = PPCISD::BCTRL_LOAD_TOC_RM;
5464 RetOpc = PPCISD::BCTRL_RM;
5466 case PPCISD::BL_LOAD_TOC:
5467 RetOpc = PPCISD::BL_LOAD_TOC_RM;
5469 case PPCISD::CALL_NOTOC:
5470 RetOpc = PPCISD::CALL_NOTOC_RM;
5473 RetOpc = PPCISD::CALL_RM;
5475 case PPCISD::CALL_NOP:
5476 RetOpc = PPCISD::CALL_NOP_RM;
5490 auto isLocalCallee = [&]() {
5506 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5522 return getAIXFuncEntryPointSymbolSDNode(GV);
5529 const char *SymName = S->getSymbol();
5536 return getAIXFuncEntryPointSymbolSDNode(
F);
5542 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5550 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5557 assert(Callee.getNode() &&
"What no callee?");
5563 "Expected a CALLSEQ_STARTSDNode.");
5580 SDValue MTCTROps[] = {Chain, Callee, Glue};
5581 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5582 Chain = DAG.
getNode(PPCISD::MTCTR, dl, ReturnTypes,
5622 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5641 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5642 Alignment, MMOFlags);
5649 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5656 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5668 "Nest parameter is not supported on AIX.");
5683 const SDLoc &dl,
bool hasNest,
5693 Chain = MoveToPhysicalReg.
getValue(0);
5694 Glue = MoveToPhysicalReg.
getValue(1);
5701 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5704 const bool IsPPC64 = Subtarget.isPPC64();
5709 Ops.push_back(Chain);
5713 Ops.push_back(Callee);
5714 else if (Subtarget.usePointerGlueHelper()) {
5715 Ops.push_back(Callee);
5738 Ops.push_back(AddTOC);
5749 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5758 for (
const auto &[
Reg,
N] : RegsToPass)
5776 assert(Mask &&
"Missing call preserved mask for calling convention");
5781 Ops.push_back(Glue);
5784SDValue PPCTargetLowering::FinishCall(
5791 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5792 Subtarget.isAIXABI())
5799 if (!CFlags.IsIndirect)
5801 else if (Subtarget.usesFunctionDescriptors()) {
5802 if (Subtarget.usePointerGlueHelper()) {
5804 CFlags.HasNest, Subtarget);
5805 SDValue PtrGlueCallee =
5810 dl, CFlags.HasNest, Subtarget);
5822 if (CFlags.IsTailCall) {
5830 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5831 "Expecting a global address, external symbol, absolute value, "
5832 "register or an indirect tail call when PC Relative calls are "
5835 assert(CallOpc == PPCISD::TC_RETURN &&
5836 "Unexpected call opcode for a tail call.");
5838 SDValue Ret = DAG.
getNode(CallOpc, dl, MVT::Other,
Ops);
5843 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5844 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5856 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5859 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5879 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5880 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5884bool PPCTargetLowering::isEligibleForTCO(
5889 bool isCalleeExternalSymbol)
const {
5893 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5894 return IsEligibleForTailCallOptimization_64SVR4(
5895 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5896 isCalleeExternalSymbol);
5898 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5926 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5941 "Callee should be an llvm::Function object.");
5944 <<
"\nTCO callee: ");
5951 "site marked musttail");
5958 Callee = LowerGlobalAddress(Callee, DAG);
5961 CallConv, isTailCall, isVarArg, isPatchPoint,
5964 Subtarget.is64BitELFABI() &&
5968 if (Subtarget.isAIXABI())
5969 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5972 assert(Subtarget.isSVR4ABI());
5973 if (Subtarget.isPPC64())
5974 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5976 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5980SDValue PPCTargetLowering::LowerCall_32SVR4(
5991 const bool IsVarArg = CFlags.IsVarArg;
5992 const bool IsTailCall = CFlags.IsTailCall;
5998 const Align PtrAlign(4);
6009 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6017 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6020 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6027 unsigned NumArgs = Outs.
size();
6029 for (
unsigned i = 0; i != NumArgs; ++i) {
6030 MVT ArgVT = Outs[i].VT;
6031 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6036 Outs[i].OrigTy, CCInfo);
6039 ArgFlags, Outs[i].OrigTy, CCInfo);
6044 errs() <<
"Call operand #" << i <<
" has unhandled type "
6057 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6060 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6067 unsigned NumBytes = CCByValInfo.getStackSize();
6076 SDValue CallSeqStart = Chain;
6081 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6092 bool seenFloatArg =
false;
6097 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6099 ++i, ++RealArgIdx) {
6100 CCValAssign &VA = ArgLocs[i];
6101 SDValue Arg = OutVals[RealArgIdx];
6102 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6104 if (
Flags.isByVal()) {
6109 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6110 CCValAssign &ByValVA = ByValArgLocs[
j++];
6122 SDValue MemcpyCall =
6132 Chain = CallSeqStart = NewCallSeqStart;
6151 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6152 bool IsLE = Subtarget.isLittleEndian();
6153 SDValue SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6156 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
6158 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6173 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6182 if (!MemOpChains.
empty())
6188 for (
const auto &[
Reg,
N] : RegsToPass) {
6196 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6197 SDValue
Ops[] = { Chain, InGlue };
6199 Chain = DAG.
getNode(seenFloatArg ? PPCISD::CR6SET : PPCISD::CR6UNSET, dl,
6209 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6210 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6215SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6227 return NewCallSeqStart;
6230SDValue PPCTargetLowering::LowerCall_64SVR4(
6237 bool isELFv2ABI = Subtarget.isELFv2ABI();
6238 bool isLittleEndian = Subtarget.isLittleEndian();
6240 bool IsSibCall =
false;
6244 unsigned PtrByteSize = 8;
6257 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6259 assert(!(IsFastCall && CFlags.IsVarArg) &&
6260 "fastcc not supported on varargs functions");
6266 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6267 unsigned NumBytes = LinkageSize;
6268 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6271 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6272 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6275 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6276 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6279 const unsigned NumGPRs = std::size(GPR);
6281 const unsigned NumVRs = std::size(VR);
6287 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6288 if (!HasParameterArea) {
6289 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6290 unsigned AvailableFPRs = NumFPRs;
6291 unsigned AvailableVRs = NumVRs;
6292 unsigned NumBytesTmp = NumBytes;
6293 for (
unsigned i = 0; i !=
NumOps; ++i) {
6294 if (Outs[i].
Flags.isNest())
continue;
6296 PtrByteSize, LinkageSize, ParamAreaSize,
6297 NumBytesTmp, AvailableFPRs, AvailableVRs))
6298 HasParameterArea =
true;
6304 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6309 HasParameterArea =
false;
6312 for (
unsigned i = 0; i !=
NumOps; ++i) {
6313 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6314 EVT ArgVT = Outs[i].VT;
6315 EVT OrigVT = Outs[i].ArgVT;
6321 if (
Flags.isByVal()) {
6322 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6323 if (NumGPRsUsed > NumGPRs)
6324 HasParameterArea =
true;
6331 if (++NumGPRsUsed <= NumGPRs)
6341 if (++NumVRsUsed <= NumVRs)
6345 if (++NumVRsUsed <= NumVRs)
6350 if (++NumFPRsUsed <= NumFPRs)
6354 HasParameterArea =
true;
6361 NumBytes =
alignTo(NumBytes, Alignement);
6364 if (
Flags.isInConsecutiveRegsLast())
6365 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6368 unsigned NumBytesActuallyUsed = NumBytes;
6378 if (HasParameterArea)
6379 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6381 NumBytes = LinkageSize;
6396 if (CFlags.IsTailCall)
6403 SDValue CallSeqStart = Chain;
6408 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6419 unsigned ArgOffset = LinkageSize;
6425 for (
unsigned i = 0; i !=
NumOps; ++i) {
6426 SDValue Arg = OutVals[i];
6427 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6428 EVT ArgVT = Outs[i].VT;
6429 EVT OrigVT = Outs[i].ArgVT;
6438 auto ComputePtrOff = [&]() {
6442 ArgOffset =
alignTo(ArgOffset, Alignment);
6453 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6454 GPR_idx = std::min(GPR_idx, NumGPRs);
6461 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6467 if (
Flags.isByVal()) {
6485 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6486 if (GPR_idx != NumGPRs) {
6488 MachinePointerInfo(), VT);
6492 ArgOffset += PtrByteSize;
6497 if (GPR_idx == NumGPRs &&
Size < 8) {
6498 SDValue AddPtr = PtrOff;
6499 if (!isLittleEndian) {
6504 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6507 ArgOffset += PtrByteSize;
6516 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6517 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6522 if (
Size < 8 && GPR_idx != NumGPRs) {
6531 SDValue AddPtr = PtrOff;
6532 if (!isLittleEndian) {
6536 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6542 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6547 ArgOffset += PtrByteSize;
6553 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6556 if (GPR_idx != NumGPRs) {
6557 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6560 MachinePointerInfo(), ObjType);
6564 ArgOffset += PtrByteSize;
6566 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6578 if (
Flags.isNest()) {
6580 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6587 if (GPR_idx != NumGPRs) {
6588 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6593 assert(HasParameterArea &&
6594 "Parameter area must exist to pass an argument in memory.");
6596 true, CFlags.IsTailCall,
false, MemOpChains,
6597 TailCallArguments, dl);
6599 ArgOffset += PtrByteSize;
6602 ArgOffset += PtrByteSize;
6615 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6616 bool NeededLoad =
false;
6619 if (FPR_idx != NumFPRs)
6620 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6623 if (!NeedGPROrStack)
6625 else if (GPR_idx != NumGPRs && !IsFastCall) {
6639 }
else if (!
Flags.isInConsecutiveRegs()) {
6645 }
else if (ArgOffset % PtrByteSize != 0) {
6649 if (!isLittleEndian)
6654 }
else if (
Flags.isInConsecutiveRegsLast()) {
6657 if (!isLittleEndian)
6667 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6675 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6680 assert(HasParameterArea &&
6681 "Parameter area must exist to pass an argument in memory.");
6683 true, CFlags.IsTailCall,
false, MemOpChains,
6684 TailCallArguments, dl);
6691 if (!IsFastCall || NeededLoad) {
6693 Flags.isInConsecutiveRegs()) ? 4 : 8;
6694 if (
Flags.isInConsecutiveRegsLast())
6695 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6715 if (CFlags.IsVarArg) {
6716 assert(HasParameterArea &&
6717 "Parameter area must exist if we have a varargs call.");
6721 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6723 if (VR_idx != NumVRs) {
6725 DAG.
getLoad(MVT::v4f32, dl,
Store, PtrOff, MachinePointerInfo());
6730 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6731 if (GPR_idx == NumGPRs)
6736 DAG.
getLoad(PtrVT, dl,
Store, Ix, MachinePointerInfo());
6744 if (VR_idx != NumVRs) {
6745 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6750 assert(HasParameterArea &&
6751 "Parameter area must exist to pass an argument in memory.");
6753 true, CFlags.IsTailCall,
true, MemOpChains,
6754 TailCallArguments, dl);
6765 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6766 "mismatch in size of parameter area");
6767 (void)NumBytesActuallyUsed;
6769 if (!MemOpChains.
empty())
6775 if (CFlags.IsIndirect) {
6779 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6784 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6794 if (isELFv2ABI && !CFlags.IsPatchPoint)
6795 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6801 for (
const auto &[
Reg,
N] : RegsToPass) {
6806 if (CFlags.IsTailCall && !IsSibCall)
6810 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6811 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6818 "Required alignment greater than stack alignment.");
6838 return RequiredAlign <= 8;
6843 return RequiredAlign <= 4;
6851 State.getMachineFunction().getSubtarget());
6852 const bool IsPPC64 = Subtarget.isPPC64();
6853 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6854 const Align PtrAlign(PtrSize);
6855 const Align StackAlign(16);
6858 if (ValVT == MVT::f128)
6862 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6863 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6865 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6866 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6869 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6870 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6871 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6876 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6885 if (ByValAlign > StackAlign)
6887 "16 are not supported.");
6890 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6894 if (ByValSize == 0) {
6896 State.getStackSize(), RegVT, LocInfo));
6901 unsigned NextReg = State.getFirstUnallocated(GPRs);
6902 while (NextReg != GPRs.
size() &&
6907 State.AllocateStack(PtrSize, PtrAlign);
6908 assert(
Reg &&
"Alocating register unexpectedly failed.");
6910 NextReg = State.getFirstUnallocated(GPRs);
6913 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6914 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6934 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6938 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6957 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
6963 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6965 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6966 if (State.isVarArg()) {
6998 const unsigned VecSize = 16;
6999 const Align VecAlign(VecSize);
7001 if (!State.isVarArg()) {
7004 if (
MCRegister VReg = State.AllocateReg(VR)) {
7011 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7016 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7019 while (NextRegIndex != GPRs.
size() &&
7023 State.AllocateStack(PtrSize, PtrAlign);
7024 assert(
Reg &&
"Allocating register unexpectedly failed.");
7026 NextRegIndex = State.getFirstUnallocated(GPRs);
7034 if (
MCRegister VReg = State.AllocateReg(VR)) {
7037 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7038 State.AllocateReg(GPRs);
7039 State.AllocateStack(VecSize, VecAlign);
7043 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7049 if (NextRegIndex == GPRs.
size()) {
7050 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7058 if (GPRs[NextRegIndex] == PPC::R9) {
7059 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7063 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7064 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7065 assert(FirstReg && SecondReg &&
7066 "Allocating R9 or R10 unexpectedly failed.");
7077 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7080 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7082 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7097 assert((IsPPC64 || SVT != MVT::i64) &&
7098 "i64 should have been split for 32-bit codegen.");
7106 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7108 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7110 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7118 return &PPC::VRRCRegClass;
7131 else if (Flags.isZExt())
7143 "Reg must be a valid argument register!");
7144 return LASize + 4 * (
Reg - PPC::R3);
7149 "Reg must be a valid argument register!");
7150 return LASize + 8 * (
Reg - PPC::X3);
7196SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7203 "Unexpected calling convention!");
7211 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7213 const bool IsPPC64 = Subtarget.isPPC64();
7214 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7220 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7221 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7225 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7226 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7227 uint64_t SaveStackPos = CCInfo.getStackSize();
7229 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7234 CCValAssign &VA = ArgLocs[
I++];
7239 EVT ArgVT = Ins[VA.
getValNo()].ArgVT;
7240 bool ArgSignExt = Ins[VA.
getValNo()].Flags.isSExt();
7252 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7254 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7259 SDValue StoreReg = DAG.
getStore(Chain, dl, Parm, FIN,
7260 MachinePointerInfo(),
Align(PtrByteSize));
7266 unsigned StoreSize =
7268 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7271 auto HandleMemLoc = [&]() {
7274 assert((ValSize <= LocSize) &&
7275 "Object size is larger than size of MemLoc");
7278 if (LocSize > ValSize)
7279 CurArgOffset += LocSize - ValSize;
7281 const bool IsImmutable =
7287 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7305 SDValue ArgValueTrunc =
7307 SDValue ArgValueExt =
7321 assert(isVarArg &&
"Only use custom memloc for vararg.");
7324 const unsigned OriginalValNo = VA.
getValNo();
7325 (void)OriginalValNo;
7327 auto HandleCustomVecRegLoc = [&]() {
7328 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7329 "Missing custom RegLoc.");
7332 "Unexpected Val type for custom RegLoc.");
7334 "ValNo mismatch between custom MemLoc and RegLoc.");
7338 Subtarget.hasVSX()));
7345 HandleCustomVecRegLoc();
7346 HandleCustomVecRegLoc();
7350 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7352 "Only 2 custom RegLocs expected for 64-bit codegen.");
7353 HandleCustomVecRegLoc();
7354 HandleCustomVecRegLoc();
7398 const unsigned Size =
7410 if (
Flags.isByVal()) {
7414 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7416 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7425 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7427 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7440 CopyFrom.
getValue(1), dl, CopyFrom,
7450 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7453 "RegLocs should be for ByVal argument.");
7455 const CCValAssign RL = ArgLocs[
I++];
7460 if (
Offset != StackSize) {
7462 "Expected MemLoc for remaining bytes.");
7463 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7477 Subtarget.hasVSX()));
7494 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7496 unsigned CallerReservedArea = std::max<unsigned>(
7497 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7503 CallerReservedArea =
7508 int VAListIndex = 0;
7512 if (CCInfo.getStackSize() < (LinkageSize + MinParameterSaveArea)) {
7513 unsigned FixedStackSize =
7514 LinkageSize + MinParameterSaveArea - CCInfo.getStackSize();
7530 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7531 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7533 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7534 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7535 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7541 GPRIndex = (CCInfo.getStackSize() - LinkageSize) / PtrByteSize,
7543 GPRIndex < NumGPArgRegs; ++GPRIndex,
Offset += PtrByteSize) {
7546 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7547 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7550 MachinePointerInfo MPI =
7555 SDValue PtrOff = DAG.
getConstant(PtrByteSize, dl, PtrVT);
7560 if (!MemOps.
empty())
7566SDValue PPCTargetLowering::LowerCall_AIX(
7579 "Unexpected calling convention!");
7581 if (CFlags.IsPatchPoint)
7584 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7588 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7595 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7596 const bool IsPPC64 = Subtarget.isPPC64();
7598 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7599 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7600 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7608 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7609 const unsigned NumBytes = std::max<unsigned>(
7610 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7615 SDValue CallSeqStart = Chain;
7626 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7627 const unsigned ValNo = ArgLocs[
I].getValNo();
7628 SDValue Arg = OutVals[ValNo];
7629 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7631 if (
Flags.isByVal()) {
7632 const unsigned ByValSize =
Flags.getByValSize();
7640 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7646 MachinePointerInfo(), VT);
7649 unsigned LoadOffset = 0;
7652 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7653 SDValue
Load = GetLoad(PtrVT, LoadOffset);
7655 LoadOffset += PtrByteSize;
7656 const CCValAssign &ByValVA = ArgLocs[
I++];
7658 "Unexpected location for pass-by-value argument.");
7662 if (LoadOffset == ByValSize)
7666 assert(ArgLocs[
I].getValNo() == ValNo &&
7667 "Expected additional location for by-value argument.");
7669 if (ArgLocs[
I].isMemLoc()) {
7670 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7671 const CCValAssign &ByValVA = ArgLocs[
I++];
7672 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7675 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7681 CallSeqStart, MemcpyFlags, DAG, dl);
7690 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7691 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7692 "Unexpected register residue for by-value argument.");
7694 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7698 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7699 SDValue
Load = GetLoad(VT, LoadOffset);
7708 "Unexpected load emitted during handling of pass-by-value "
7713 SDValue SHLAmt = DAG.
getConstant(NumSHLBits, dl, ShiftAmountTy);
7714 SDValue ShiftedLoad =
7716 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7721 const CCValAssign &ByValVA = ArgLocs[
I++];
7726 CCValAssign &VA = ArgLocs[
I++];
7751 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7757 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7759 const unsigned OriginalValNo = VA.
getValNo();
7761 unsigned LoadOffset = 0;
7762 auto HandleCustomVecRegLoc = [&]() {
7763 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7764 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7765 "Expected custom RegLoc.");
7766 CCValAssign RegVA = ArgLocs[
I++];
7768 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7774 LoadOffset += PtrByteSize;
7780 HandleCustomVecRegLoc();
7781 HandleCustomVecRegLoc();
7783 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7784 ArgLocs[
I].getValNo() == OriginalValNo) {
7786 "Only 2 custom RegLocs expected for 64-bit codegen.");
7787 HandleCustomVecRegLoc();
7788 HandleCustomVecRegLoc();
7799 DAG.
getStore(Chain, dl, Arg, PtrOff,
7801 Subtarget.getFrameLowering()->getStackAlign()));
7808 "Unexpected register handling for calling convention.");
7814 "Custom register handling only expected for VarArg.");
7819 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7823 else if (Arg.getValueType().getFixedSizeInBits() <
7831 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7832 "Unexpected custom register for argument!");
7833 CCValAssign &GPR1 = VA;
7842 CCValAssign &PeekArg = ArgLocs[
I];
7845 CCValAssign &GPR2 = ArgLocs[
I++];
7853 if (!MemOpChains.
empty())
7858 if (CFlags.IsIndirect && !Subtarget.usePointerGlueHelper()) {
7859 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7860 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7861 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7862 const MVT PtrVT = Subtarget.getScalarIntVT();
7863 const unsigned TOCSaveOffset =
7864 Subtarget.getFrameLowering()->getTOCSaveOffset();
7879 for (
auto Reg : RegsToPass) {
7884 const int SPDiff = 0;
7885 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7886 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7894 const Type *RetTy)
const {
7896 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7897 return CCInfo.CheckReturn(
7912 CCInfo.AnalyzeReturn(Outs,
7921 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7922 CCValAssign &VA = RVLocs[i];
7925 SDValue Arg = OutVals[RealResIdx];
7940 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7941 bool isLittleEndian = Subtarget.isLittleEndian();
7944 DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7948 SVal = DAG.
getNode(PPCISD::EXTRACT_SPE, dl, MVT::i32, Arg,
7963 RetOps.push_back(Glue);
7965 return DAG.
getNode(PPCISD::RET_GLUE, dl, MVT::Other, RetOps);
7969PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7974 EVT IntVT =
Op.getValueType();
7977 SDValue Chain =
Op.getOperand(0);
7978 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7980 SDValue
Ops[2] = {Chain, FPSIdx};
7982 return DAG.
getNode(PPCISD::DYNAREAOFFSET, dl, VTs,
Ops);
7994 bool isPPC64 = Subtarget.isPPC64();
7995 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7999 SDValue Chain =
Op.getOperand(0);
8000 SDValue SaveSP =
Op.getOperand(1);
8003 SDValue LoadLinkSP =
8004 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
8010 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8015 bool isPPC64 = Subtarget.isPPC64();
8020 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8026 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8036PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8038 bool isPPC64 = Subtarget.isPPC64();
8043 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8049 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8062 SDValue Chain =
Op.getOperand(0);
8063 SDValue
Size =
Op.getOperand(1);
8072 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8073 SDValue
Ops[3] = { Chain, NegSize, FPSIdx };
8074 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8076 return DAG.
getNode(PPCISD::PROBED_ALLOCA, dl, VTs,
Ops);
8077 return DAG.
getNode(PPCISD::DYNALLOC, dl, VTs,
Ops);
8084 bool isPPC64 = Subtarget.isPPC64();
8094 return DAG.
getNode(PPCISD::EH_SJLJ_SETJMP,
DL,
8096 Op.getOperand(0),
Op.getOperand(1));
8102 return DAG.
getNode(PPCISD::EH_SJLJ_LONGJMP,
DL, MVT::Other,
8103 Op.getOperand(0),
Op.getOperand(1));
8107 if (
Op.getValueType().isVector())
8108 return LowerVectorLoad(
Op, DAG);
8110 assert(
Op.getValueType() == MVT::i1 &&
8111 "Custom lowering only for i1 loads");
8118 SDValue Chain =
LD->getChain();
8120 MachineMemOperand *MMO =
LD->getMemOperand();
8124 BasePtr, MVT::i8, MMO);
8132 if (
Op.getOperand(1).getValueType().isVector())
8133 return LowerVectorStore(
Op, DAG);
8135 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8136 "Custom lowering only for i1 stores");
8143 SDValue Chain =
ST->getChain();
8145 SDValue
Value =
ST->getValue();
8146 MachineMemOperand *MMO =
ST->getMemOperand();
8155 assert(
Op.getValueType() == MVT::i1 &&
8156 "Custom lowering only for i1 results");
8184 EVT TrgVT =
Op.getValueType();
8193 SDValue N1 =
Op.getOperand(0);
8208 if (SrcSize == 256) {
8219 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8225 SmallVector<int, 16> ShuffV;
8226 if (Subtarget.isLittleEndian())
8227 for (
unsigned i = 0; i < TrgNumElts; ++i)
8230 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8234 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8247 EVT ResVT =
Op.getValueType();
8248 EVT CmpVT =
Op.getOperand(0).getValueType();
8249 SDValue
LHS =
Op.getOperand(0),
RHS =
Op.getOperand(1);
8250 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8256 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8269 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8273 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8290 if (!
Flags.hasNoInfs() || !
Flags.hasNoNaNs() || ResVT == MVT::f128)
8303 if (
LHS.getValueType() == MVT::f32)
8305 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8306 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8314 if (
LHS.getValueType() == MVT::f32)
8316 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
LHS, TV, FV);
8323 if (
LHS.getValueType() == MVT::f32)
8325 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8337 if (
Cmp.getValueType() == MVT::f32)
8339 Sel1 = DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8340 return DAG.
getNode(PPCISD::FSEL, dl, ResVT,
8345 if (
Cmp.getValueType() == MVT::f32)
8347 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8351 if (
Cmp.getValueType() == MVT::f32)
8353 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8357 if (
Cmp.getValueType() == MVT::f32)
8359 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, FV, TV);
8363 if (
Cmp.getValueType() == MVT::f32)
8365 return DAG.
getNode(PPCISD::FSEL, dl, ResVT, Cmp, TV, FV);
8374 case PPCISD::FCTIDZ:
8375 return PPCISD::STRICT_FCTIDZ;
8376 case PPCISD::FCTIWZ:
8377 return PPCISD::STRICT_FCTIWZ;
8378 case PPCISD::FCTIDUZ:
8379 return PPCISD::STRICT_FCTIDUZ;
8380 case PPCISD::FCTIWUZ:
8381 return PPCISD::STRICT_FCTIWUZ;
8383 return PPCISD::STRICT_FCFID;
8384 case PPCISD::FCFIDU:
8385 return PPCISD::STRICT_FCFIDU;
8386 case PPCISD::FCFIDS:
8387 return PPCISD::STRICT_FCFIDS;
8388 case PPCISD::FCFIDUS:
8389 return PPCISD::STRICT_FCFIDUS;
8396 bool IsStrict =
Op->isStrictFPOpcode();
8405 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8407 MVT DestTy =
Op.getSimpleValueType();
8408 assert(Src.getValueType().isFloatingPoint() &&
8409 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8410 DestTy == MVT::i64) &&
8411 "Invalid FP_TO_INT types");
8412 if (Src.getValueType() == MVT::f32) {
8416 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8421 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8427 Opc = IsSigned ? PPCISD::FCTIWZ
8428 : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ : PPCISD::FCTIDZ);
8431 assert((IsSigned || Subtarget.hasFPCVT()) &&
8432 "i64 FP_TO_UINT is supported only with FPCVT");
8433 Opc = IsSigned ? PPCISD::FCTIDZ : PPCISD::FCTIDUZ;
8435 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8447void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8449 const SDLoc &dl)
const {
8453 bool IsStrict =
Op->isStrictFPOpcode();
8456 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8457 (IsSigned || Subtarget.hasFPCVT());
8460 MachinePointerInfo MPI =
8469 MachineMemOperand *MMO =
8471 SDValue
Ops[] = { Chain, Tmp, FIPtr };
8475 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8479 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8480 !Subtarget.isLittleEndian()) {
8497 const SDLoc &dl)
const {
8499 SDValue Mov = DAG.
getNode(PPCISD::MFVSR, dl,
Op.getValueType(), Conv);
8500 if (
Op->isStrictFPOpcode())
8507 const SDLoc &dl)
const {
8508 bool IsStrict =
Op->isStrictFPOpcode();
8511 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8512 EVT SrcVT = Src.getValueType();
8513 EVT DstVT =
Op.getValueType();
8516 if (SrcVT == MVT::f128)
8517 return Subtarget.hasP9Vector() ?
Op : SDValue();
8521 if (SrcVT == MVT::ppcf128) {
8522 if (DstVT == MVT::i32) {
8527 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8536 SDValue Res = DAG.
getNode(PPCISD::STRICT_FADDRTZ, dl,
8538 {Op.getOperand(0), Lo, Hi}, Flags);
8541 {Res.getValue(1), Res}, Flags);
8543 SDValue Res = DAG.
getNode(PPCISD::FADDRTZ, dl, MVT::f64,
Lo,
Hi);
8547 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8550 SDValue SignMask = DAG.
getConstant(0x80000000, dl, DstVT);
8556 SDValue Chain =
Op.getOperand(0);
8571 {Chain, Src, FltOfs}, Flags);
8575 {Chain, Val}, Flags);
8578 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8596 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8597 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8600 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8602 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8603 RLI.Alignment, RLI.MMOFlags(),
8604 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8615bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8620 if (
Op->isStrictFPOpcode())
8625 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8629 Op.getOperand(0).getValueType())) {
8631 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8636 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8637 LD->isNonTemporal())
8639 if (
LD->getMemoryVT() != MemVT)
8649 RLI.Ptr =
LD->getBasePtr();
8650 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8652 "Non-pre-inc AM on PPC?");
8657 RLI.Chain =
LD->getChain();
8658 RLI.MPI =
LD->getPointerInfo();
8659 RLI.IsDereferenceable =
LD->isDereferenceable();
8660 RLI.IsInvariant =
LD->isInvariant();
8661 RLI.Alignment =
LD->getAlign();
8662 RLI.AAInfo =
LD->getAAInfo();
8663 RLI.Ranges =
LD->getRanges();
8665 RLI.ResChain = SDValue(LD,
LD->isIndexed() ? 2 : 1);
8672bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8673 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8680 if (!Subtarget.hasP9Vector() &&
8684 for (SDUse &Use : Origin->
uses()) {
8687 if (
Use.getResNo() != 0)
8714 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8715 unsigned ConvOpc = IsSingle ? (IsSigned ? PPCISD::FCFIDS : PPCISD::FCFIDUS)
8716 : (IsSigned ? PPCISD::FCFID : PPCISD::FCFIDU);
8717 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8718 if (
Op->isStrictFPOpcode()) {
8720 Chain =
Op.getOperand(0);
8722 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8724 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8732 const SDLoc &dl)
const {
8733 assert((
Op.getValueType() == MVT::f32 ||
8734 Op.getValueType() == MVT::f64) &&
8735 "Invalid floating point type as target of conversion");
8736 assert(Subtarget.hasFPCVT() &&
8737 "Int to FP conversions with direct moves require FPCVT");
8738 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8739 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8742 unsigned MovOpc = (WordInt && !
Signed) ? PPCISD::MTVSRZ : PPCISD::MTVSRA;
8743 SDValue Mov = DAG.
getNode(MovOpc, dl, MVT::f64, Src);
8761 for (
unsigned i = 1; i < NumConcat; ++i)
8768 const SDLoc &dl)
const {
8769 bool IsStrict =
Op->isStrictFPOpcode();
8770 unsigned Opc =
Op.getOpcode();
8771 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8774 "Unexpected conversion type");
8775 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8776 "Supports conversions to v2f64/v4f32 only.");
8780 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8783 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8785 SDValue Wide =
widenVec(DAG, Src, dl);
8788 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8790 SmallVector<int, 16> ShuffV;
8791 for (
unsigned i = 0; i < WideNumElts; ++i)
8794 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8795 int SaveElts = FourEltRes ? 4 : 2;
8796 if (Subtarget.isLittleEndian())
8797 for (
int i = 0; i < SaveElts; i++)
8798 ShuffV[i * Stride] = i;
8800 for (
int i = 1; i <= SaveElts; i++)
8801 ShuffV[i * Stride - 1] = i - 1;
8803 SDValue ShuffleSrc2 =
8805 SDValue Arrange = DAG.
getVectorShuffle(WideVT, dl, Wide, ShuffleSrc2, ShuffV);
8809 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8810 EVT ExtVT = Src.getValueType();
8811 if (Subtarget.hasP9Altivec())
8822 {Op.getOperand(0), Extend}, Flags);
8824 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8832 bool IsStrict =
Op->isStrictFPOpcode();
8833 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8834 SDValue Chain = IsStrict ?
Op.getOperand(0) : DAG.
getEntryNode();
8838 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8840 EVT InVT = Src.getValueType();
8841 EVT OutVT =
Op.getValueType();
8844 return LowerINT_TO_FPVector(
Op, DAG, dl);
8847 if (
Op.getValueType() == MVT::f128)
8848 return Subtarget.hasP9Vector() ?
Op : SDValue();
8851 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8854 if (Src.getValueType() == MVT::i1) {
8866 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8867 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8868 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8870 assert((IsSigned || Subtarget.hasFPCVT()) &&
8871 "UINT_TO_FP is supported only with FPCVT");
8873 if (Src.getValueType() == MVT::i64) {
8888 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8889 !
Op->getFlags().hasApproximateFuncs()) {
8929 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8933 DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI, RLI.Alignment,
8934 RLI.MMOFlags(), MMOMetadata(RLI.AAInfo));
8937 }
else if (Subtarget.hasLFIWAX() &&
8938 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8941 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8942 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
8945 Ops, MVT::i32, MMO);
8948 }
else if (Subtarget.hasFPCVT() &&
8949 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8952 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8953 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
8956 Ops, MVT::i32, MMO);
8959 }
else if (((Subtarget.hasLFIWAX() &&
8961 (Subtarget.hasFPCVT() &&
8976 "Expected an i32 store");
8982 RLI.Alignment =
Align(4);
8986 MMOMetadata(RLI.AAInfo, RLI.Ranges));
8987 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
8989 PPCISD::LFIWZX : PPCISD::LFIWAX,
8990 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8991 Ops, MVT::i32, MMO);
8992 Chain =
Bits.getValue(1);
9000 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9004 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9013 assert(Src.getValueType() == MVT::i32 &&
9014 "Unhandled INT_TO_FP type in custom expander!");
9024 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9027 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9037 "Expected an i32 store");
9043 RLI.Alignment =
Align(4);
9048 MMOMetadata(RLI.AAInfo, RLI.Ranges));
9049 SDValue
Ops[] = { RLI.Chain, RLI.Ptr };
9053 Chain = Ld.getValue(1);
9054 if (ReusingLoad && RLI.ResChain) {
9058 assert(Subtarget.isPPC64() &&
9059 "i32->FP without LFIWAX supported only on PPC64");
9068 Chain, dl, Ext64, FIdx,
9074 MVT::f64, dl, Chain, FIdx,
9076 Chain = Ld.getValue(1);
9083 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9087 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9100 SDValue Chain =
Op.getOperand(0);
9105 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9106 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9107 if (Subtarget.isISA3_0())
9110 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9111 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9114 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9115 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9117 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9118 {DAG.
getConstant(31, Dl, MVT::i32,
true), SDValue(SetHi, 0)});
9119 return SDValue(SetLo, 0);
9126 SDValue DstFlag = DAG.
getNode(
9135 if (!Subtarget.isISA3_0()) {
9136 MFFS = DAG.
getNode(PPCISD::MFFS, Dl, {MVT::f64, MVT::Other}, Chain);
9140 if (Subtarget.isPPC64()) {
9141 if (Subtarget.isISA3_0()) {
9146 PPC::RLDIMI, Dl, MVT::i64,
9151 NewFPSCR = SDValue(InsertRN, 0);
9158 SDValue Addr = Subtarget.isLittleEndian()
9162 if (Subtarget.isISA3_0()) {
9163 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9165 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9167 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9170 PPC::RLWIMI, Dl, MVT::i32,
9171 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9172 DAG.getTargetConstant(30, Dl, MVT::i32),
9173 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9175 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9178 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9181 if (Subtarget.isISA3_0())
9182 return SDValue(DAG.
getMachineNode(PPC::MFFSCRN, Dl, {MVT::f64, MVT::Other},
9187 PPC::MTFSF, Dl, MVT::Other,
9189 return SDValue(MTFSF, 0);
9215 EVT VT =
Op.getValueType();
9219 SDValue Chain =
Op.getOperand(0);
9220 SDValue MFFS = DAG.
getNode(PPCISD::MFFS, dl, {MVT::f64, MVT::Other}, Chain);
9231 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9235 "Stack slot adjustment is valid only on big endian subtargets!");
9238 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9265 EVT VT =
Op.getValueType();
9269 VT ==
Op.getOperand(1).getValueType() &&
9274 SDValue
Lo =
Op.getOperand(0);
9275 SDValue
Hi =
Op.getOperand(1);
9276 SDValue Amt =
Op.getOperand(2);
9281 SDValue Tmp2 = DAG.
getNode(PPCISD::SHL, dl, VT,
Hi, Amt);
9282 SDValue Tmp3 = DAG.
getNode(PPCISD::SRL, dl, VT,
Lo, Tmp1);
9286 SDValue Tmp6 = DAG.
getNode(PPCISD::SHL, dl, VT,
Lo, Tmp5);
9288 SDValue OutLo = DAG.
getNode(PPCISD::SHL, dl, VT,
Lo, Amt);
9289 SDValue OutOps[] = { OutLo, OutHi };
9294 EVT VT =
Op.getValueType();
9298 VT ==
Op.getOperand(1).getValueType() &&
9303 SDValue
Lo =
Op.getOperand(0);
9304 SDValue
Hi =
Op.getOperand(1);
9305 SDValue Amt =
Op.getOperand(2);
9310 SDValue Tmp2 = DAG.
getNode(PPCISD::SRL, dl, VT,
Lo, Amt);
9311 SDValue Tmp3 = DAG.
getNode(PPCISD::SHL, dl, VT,
Hi, Tmp1);
9315 SDValue Tmp6 = DAG.
getNode(PPCISD::SRL, dl, VT,
Hi, Tmp5);
9317 SDValue OutHi = DAG.
getNode(PPCISD::SRL, dl, VT,
Hi, Amt);
9318 SDValue OutOps[] = { OutLo, OutHi };
9324 EVT VT =
Op.getValueType();
9327 VT ==
Op.getOperand(1).getValueType() &&
9331 SDValue
Lo =
Op.getOperand(0);
9332 SDValue
Hi =
Op.getOperand(1);
9333 SDValue Amt =
Op.getOperand(2);
9338 SDValue Tmp2 = DAG.
getNode(PPCISD::SRL, dl, VT,
Lo, Amt);
9339 SDValue Tmp3 = DAG.
getNode(PPCISD::SHL, dl, VT,
Hi, Tmp1);
9343 SDValue Tmp6 = DAG.
getNode(PPCISD::SRA, dl, VT,
Hi, Tmp5);
9344 SDValue OutHi = DAG.
getNode(PPCISD::SRA, dl, VT,
Hi, Amt);
9347 SDValue OutOps[] = { OutLo, OutHi };
9354 EVT VT =
Op.getValueType();
9358 SDValue
X =
Op.getOperand(0);
9359 SDValue
Y =
Op.getOperand(1);
9360 SDValue
Z =
Op.getOperand(2);
9361 EVT AmtVT =
Z.getValueType();
9371 X = DAG.
getNode(PPCISD::SHL, dl, VT,
X, IsFSHL ? Z : SubZ);
9372 Y = DAG.
getNode(PPCISD::SRL, dl, VT,
Y, IsFSHL ? SubZ : Z);
9384 static const MVT VTys[] = {
9385 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9388 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9391 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9396 EVT CanonicalVT = VTys[SplatSize-1];
9409 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9410 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9419 EVT DestVT = MVT::Other) {
9420 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9429 EVT DestVT = MVT::Other) {
9432 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9444 for (
unsigned i = 0; i != 16; ++i)
9465 EVT VecVT = V->getValueType(0);
9466 bool RightType = VecVT == MVT::v2f64 ||
9467 (HasP8Vector && VecVT == MVT::v4f32) ||
9468 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9472 bool IsSplat =
true;
9473 bool IsLoad =
false;
9479 if (V->isConstant())
9481 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9482 if (V->getOperand(i).isUndef())
9486 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9488 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9490 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9492 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9496 if (V->getOperand(i) != Op0 ||
9497 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9500 return !(IsSplat && IsLoad);
9507 SDValue Op0 =
Op->getOperand(0);
9510 (
Op.getValueType() != MVT::f128))
9515 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9518 if (!Subtarget.isLittleEndian())
9521 return DAG.
getNode(PPCISD::BUILD_FP128, dl, MVT::f128,
Lo,
Hi);
9535 InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED) {
9538 IsPermuted = InputLoad->
getOpcode() == PPCISD::SCALAR_TO_VECTOR_PERMUTED;
9551 APFloat APFloatToConvert = ArgAPFloat;
9552 bool LosesInfo =
true;
9557 ArgAPFloat = APFloatToConvert;
9579 APFloat APFloatToConvert = ArgAPFloat;
9580 bool LosesInfo =
true;
9584 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9593 EVT Ty =
Op->getValueType(0);
9596 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9605 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9609 if (Ty == MVT::v2i64) {
9612 if (MemVT == MVT::i32) {
9614 Opcode = PPCISD::ZEXT_LD_SPLAT;
9616 Opcode = PPCISD::SEXT_LD_SPLAT;
9624 bool IsLittleEndian) {
9630 APInt ConstValue(VTSize, 0);
9634 unsigned BitPos = 0;
9642 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9643 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9647 for (
unsigned J = 0; J < 16; ++J) {
9649 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9651 if (ExtractValue == 0xFF)
9666 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9668 if (Subtarget.hasP10Vector()) {
9669 APInt BitMask(32, 0);
9675 BitMask != 0 && BitMask != 0xffff) {
9677 MachineSDNode *MSDNode =
9679 SDValue SDV = SDValue(MSDNode, 0);
9689 if (SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9693 APInt APSplatBits, APSplatUndef;
9694 unsigned SplatBitSize = 0;
9696 bool BVNIsConstantSplat =
9698 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9704 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9705 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9708 if ((
Op->getValueType(0) == MVT::v2f64) &&
9710 SDValue SplatNode = DAG.
getNode(
9711 PPCISD::XXSPLTI_SP_TO_DP, dl, MVT::v2f64,
9719 SDValue SplatNode = DAG.
getUNDEF(MVT::v2i64);
9727 PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9733 DAG.
getNode(PPCISD::XXSPLTI32DX, dl, MVT::v2i64, SplatNode,
9742 LowerVecSplatSmallFP(
Op, DAG, BVNIsConstantSplat, SplatBitSize))
9745 bool IsSplat64 =
false;
9747 int32_t SextVal = 0;
9748 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9750 if (SplatBitSize <= 32) {
9752 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9753 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9754 bool P9Vector = Subtarget.hasP9Vector();
9755 int32_t
Hi = P9Vector ? 127 : 15;
9756 int32_t
Lo = P9Vector ? -128 : -16;
9757 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9758 SextVal =
static_cast<int32_t
>(SplatBits);
9762 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9763 unsigned NewOpcode = PPCISD::LD_SPLAT;
9769 const SDValue *InputLoad = &
Op.getOperand(0);
9774 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9775 unsigned ElementSize =
9776 MemorySize * ((NewOpcode == PPCISD::LD_SPLAT) ? 1 : 2);
9778 assert(((ElementSize == 2 * MemorySize)
9779 ? (NewOpcode == PPCISD::ZEXT_LD_SPLAT ||
9780 NewOpcode == PPCISD::SEXT_LD_SPLAT)
9781 : (NewOpcode == PPCISD::LD_SPLAT)) &&
9782 "Unmatched element size and opcode!\n");
9787 unsigned NumUsesOfInputLD = 128 / ElementSize;
9788 for (SDValue BVInOp :
Op->ops())
9789 if (BVInOp.isUndef())
9804 if (NumUsesOfInputLD == 1 &&
9805 (
Op->getValueType(0) == MVT::v2i64 && NewOpcode != PPCISD::LD_SPLAT &&
9806 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9807 Subtarget.hasLFIWAX()))
9815 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9816 Subtarget.isISA3_1() && ElementSize <= 16)
9819 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9821 Subtarget.hasVSX()) {
9828 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9829 LD->getMemoryVT(),
LD->getMemOperand());
9841 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9843 Subtarget.hasP8Vector()))
9849 unsigned SplatSize = SplatBitSize / 8;
9854 if (SplatBits == 0) {
9856 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9868 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9870 Op.getValueType(), DAG, dl);
9872 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9877 if (Subtarget.hasP9Vector() && SplatSize == 1)
9883 if (SextVal >= -16 && SextVal <= 15) {
9886 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9891 SDValue IntrinsicOp =
9893 DAG.
getBitcast(MVT::v4i32, Res), DAG, dl, MVT::v2i64);
9899 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9900 SDValue
C = DAG.
getConstant((
unsigned char)SextVal, dl, MVT::i32);
9905 switch (SplatSize) {
9909 IID = Intrinsic::ppc_altivec_vupklsb;
9913 IID = Intrinsic::ppc_altivec_vextsb2w;
9917 IID = Intrinsic::ppc_altivec_vextsb2d;
9924 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9933 if (SextVal >= -32 && SextVal <= 31) {
9938 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9939 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9940 SDValue EltSize = DAG.
getConstant(SplatSize, dl, MVT::i32);
9942 if (VT ==
Op.getValueType())
9951 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9965 static const signed char SplatCsts[] = {
9966 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9967 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9970 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9973 int i = SplatCsts[idx];
9977 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9980 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9982 static const unsigned IIDs[] = {
9983 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9984 Intrinsic::ppc_altivec_vslw
9991 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9993 static const unsigned IIDs[] = {
9994 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9995 Intrinsic::ppc_altivec_vsrw
10002 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
10003 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
10005 static const unsigned IIDs[] = {
10006 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
10007 Intrinsic::ppc_altivec_vrlw
10014 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
10016 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
10020 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10022 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
10026 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10028 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
10041 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10042 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10043 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10059 if (LHSID == (1*9+2)*9+3)
return LHS;
10060 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10072 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10073 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10074 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10075 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10078 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10079 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10080 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10081 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10084 for (
unsigned i = 0; i != 16; ++i)
10085 ShufIdxs[i] = (i&3)+0;
10088 for (
unsigned i = 0; i != 16; ++i)
10089 ShufIdxs[i] = (i&3)+4;
10092 for (
unsigned i = 0; i != 16; ++i)
10093 ShufIdxs[i] = (i&3)+8;
10096 for (
unsigned i = 0; i != 16; ++i)
10097 ShufIdxs[i] = (i&3)+12;
10118 const unsigned BytesInVector = 16;
10119 bool IsLE = Subtarget.isLittleEndian();
10121 SDValue
V1 =
N->getOperand(0);
10122 SDValue V2 =
N->getOperand(1);
10123 unsigned ShiftElts = 0, InsertAtByte = 0;
10127 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10128 0, 15, 14, 13, 12, 11, 10, 9};
10129 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10130 1, 2, 3, 4, 5, 6, 7, 8};
10132 ArrayRef<int>
Mask =
N->getMask();
10133 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10145 bool FoundCandidate =
false;
10149 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10152 for (
unsigned i = 0; i < BytesInVector; ++i) {
10153 unsigned CurrentElement =
Mask[i];
10156 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10159 bool OtherElementsInOrder =
true;
10162 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10169 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10170 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10171 OtherElementsInOrder =
false;
10178 if (OtherElementsInOrder) {
10185 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10186 : BigEndianShifts[CurrentElement & 0xF];
10187 Swap = CurrentElement < BytesInVector;
10189 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10190 FoundCandidate =
true;
10195 if (!FoundCandidate)
10205 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10207 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, Shl,
10210 return DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v16i8,
V1, V2,
10219 const unsigned NumHalfWords = 8;
10220 const unsigned BytesInVector = NumHalfWords * 2;
10225 bool IsLE = Subtarget.isLittleEndian();
10227 SDValue
V1 =
N->getOperand(0);
10229 unsigned ShiftElts = 0, InsertAtByte = 0;
10233 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10234 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10237 uint32_t OriginalOrderLow = 0x1234567;
10238 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10241 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10242 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10259 bool FoundCandidate =
false;
10262 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10263 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10265 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10266 uint32_t TargetOrder = 0x0;
10273 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10274 TargetOrder = OriginalOrderLow;
10278 if (MaskOneElt == VINSERTHSrcElem &&
10279 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10280 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10281 FoundCandidate =
true;
10287 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10289 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10291 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10292 : BigEndianShifts[MaskOneElt & 0x7];
10293 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10294 Swap = MaskOneElt < NumHalfWords;
10295 FoundCandidate =
true;
10301 if (!FoundCandidate)
10313 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v16i8, V2, V2,
10316 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10321 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v8i16, Conv1, Conv2,
10336 auto ShuffleMask = SVN->
getMask();
10351 ShuffleMask = CommutedSV->
getMask();
10360 APInt APSplatValue, APSplatUndef;
10361 unsigned SplatBitSize;
10364 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10376 bool IsLE = Subtarget.isLittleEndian();
10377 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10378 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10379 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10381 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10382 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10383 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10391 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10392 SplatVal |= (SplatVal << SplatBitSize);
10394 SDValue SplatNode = DAG.
getNode(
10395 PPCISD::XXSPLTI32DX,
DL, MVT::v2i64, DAG.
getBitcast(MVT::v2i64,
LHS),
10406 assert(
Op.getValueType() == MVT::v1i128 &&
10407 "Only set v1i128 as custom, other type shouldn't reach here!");
10412 if (SHLAmt % 8 == 0) {
10413 std::array<int, 16>
Mask;
10414 std::iota(
Mask.begin(),
Mask.end(), 0);
10415 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10416 if (SDValue Shuffle =
10421 SDValue ArgVal = DAG.
getBitcast(MVT::i128, N0);
10426 SDValue OROp = DAG.
getNode(
ISD::OR, dl, MVT::i128, SHLOp, SRLOp);
10437 SDValue
V1 =
Op.getOperand(0);
10438 SDValue V2 =
Op.getOperand(1);
10444 if (SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10449 V1 =
Op.getOperand(0);
10450 V2 =
Op.getOperand(1);
10452 EVT VT =
Op.getValueType();
10453 bool isLittleEndian = Subtarget.isLittleEndian();
10455 unsigned ShiftElts, InsertAtByte;
10463 bool IsPermutedLoad =
false;
10465 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10474 if (IsPermutedLoad) {
10475 assert((isLittleEndian || IsFourByte) &&
10476 "Unexpected size for permuted load on big endian target");
10477 SplatIdx += IsFourByte ? 2 : 1;
10478 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10479 "Splat of a value outside of the loaded memory");
10484 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10487 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10489 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10493 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10506 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10509 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10518 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10521 if (Subtarget.hasP9Vector() &&
10531 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv2, Conv2,
10533 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Shl,
10537 SDValue Ins = DAG.
getNode(PPCISD::VECINSERT, dl, MVT::v4i32, Conv1, Conv2,
10542 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10543 SDValue SplatInsertNode;
10544 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10545 return SplatInsertNode;
10548 if (Subtarget.hasP9Altivec()) {
10549 SDValue NewISDNode;
10550 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10553 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10557 if (Subtarget.hasVSX() &&
10565 SDValue Shl = DAG.
getNode(PPCISD::VECSHL, dl, MVT::v4i32, Conv1, Conv2,
10570 if (Subtarget.hasVSX() &&
10578 SDValue PermDI = DAG.
getNode(PPCISD::XXPERMDI, dl, MVT::v2i64, Conv1, Conv2,
10583 if (Subtarget.hasP9Vector()) {
10603 if (Subtarget.hasVSX()) {
10608 SDValue
Splat = DAG.
getNode(PPCISD::XXSPLT, dl, MVT::v4i32, Conv,
10616 SDValue
Swap = DAG.
getNode(PPCISD::SWAP_NO_CHAIN, dl, MVT::v2f64, Conv);
10624 if (V2.isUndef()) {
10637 (Subtarget.hasP8Altivec() && (
10648 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10658 (Subtarget.hasP8Altivec() && (
10666 ArrayRef<int> PermMask = SVOp->
getMask();
10669 unsigned PFIndexes[4];
10670 bool isFourElementShuffle =
true;
10671 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10673 unsigned EltNo = 8;
10674 for (
unsigned j = 0;
j != 4; ++
j) {
10675 if (PermMask[i * 4 + j] < 0)
10678 unsigned ByteSource = PermMask[i * 4 +
j];
10679 if ((ByteSource & 3) != j) {
10680 isFourElementShuffle =
false;
10685 EltNo = ByteSource / 4;
10686 }
else if (EltNo != ByteSource / 4) {
10687 isFourElementShuffle =
false;
10691 PFIndexes[i] = EltNo;
10699 if (isFourElementShuffle) {
10701 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10702 PFIndexes[2] * 9 + PFIndexes[3];
10705 unsigned Cost = (PFEntry >> 30);
10725 if (V2.isUndef()) V2 =
V1;
10727 return LowerVPERM(
Op, DAG, PermMask, VT,
V1, V2);
10733 unsigned Opcode = PPCISD::VPERM;
10736 bool NeedSwap =
false;
10737 bool isLittleEndian = Subtarget.isLittleEndian();
10738 bool isPPC64 = Subtarget.isPPC64();
10740 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10742 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10743 "XXPERM instead\n");
10744 Opcode = PPCISD::XXPERM;
10749 if ((!isLittleEndian && !V2->
hasOneUse() &&
V1->hasOneUse()) ||
10750 (isLittleEndian && !
V1->hasOneUse() && V2->
hasOneUse())) {
10752 NeedSwap = !NeedSwap;
10766 bool V1HasXXSWAPD =
V1->getOperand(0)->getOpcode() == PPCISD::XXSWAPD;
10787 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10789 if (V1HasXXSWAPD) {
10792 else if (SrcElt < 16)
10795 if (V2HasXXSWAPD) {
10798 else if (SrcElt > 15)
10807 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10808 if (isLittleEndian)
10810 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10813 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10816 if (V1HasXXSWAPD) {
10817 dl = SDLoc(
V1->getOperand(0));
10818 V1 =
V1->getOperand(0)->getOperand(1);
10820 if (V2HasXXSWAPD) {
10825 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10826 if (ValType != MVT::v2f64)
10832 ShufflesHandledWithVPERM++;
10833 SDValue VPermMask = DAG.
getBuildVector(MVT::v16i8, dl, ResultMask);
10836 if (Opcode == PPCISD::XXPERM) {
10837 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10839 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10842 dbgs() <<
"With the following permute control vector:\n";
10846 if (Opcode == PPCISD::XXPERM)
10847 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10851 if (isLittleEndian)
10854 SDValue VPERMNode =
10855 DAG.
getNode(Opcode, dl,
V1.getValueType(),
V1, V2, VPermMask);
10857 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10869 switch (IntrinsicID) {
10873 case Intrinsic::ppc_altivec_vcmpbfp_p:
10877 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10881 case Intrinsic::ppc_altivec_vcmpequb_p:
10885 case Intrinsic::ppc_altivec_vcmpequh_p:
10889 case Intrinsic::ppc_altivec_vcmpequw_p:
10893 case Intrinsic::ppc_altivec_vcmpequd_p:
10894 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10900 case Intrinsic::ppc_altivec_vcmpneb_p:
10901 case Intrinsic::ppc_altivec_vcmpneh_p:
10902 case Intrinsic::ppc_altivec_vcmpnew_p:
10903 case Intrinsic::ppc_altivec_vcmpnezb_p:
10904 case Intrinsic::ppc_altivec_vcmpnezh_p:
10905 case Intrinsic::ppc_altivec_vcmpnezw_p:
10906 if (Subtarget.hasP9Altivec()) {
10907 switch (IntrinsicID) {
10910 case Intrinsic::ppc_altivec_vcmpneb_p:
10913 case Intrinsic::ppc_altivec_vcmpneh_p:
10916 case Intrinsic::ppc_altivec_vcmpnew_p:
10919 case Intrinsic::ppc_altivec_vcmpnezb_p:
10922 case Intrinsic::ppc_altivec_vcmpnezh_p:
10925 case Intrinsic::ppc_altivec_vcmpnezw_p:
10933 case Intrinsic::ppc_altivec_vcmpgefp_p:
10937 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10941 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10945 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10949 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10953 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10954 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10960 case Intrinsic::ppc_altivec_vcmpgtub_p:
10964 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10968 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10972 case Intrinsic::ppc_altivec_vcmpgtud_p:
10973 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10980 case Intrinsic::ppc_altivec_vcmpequq:
10981 case Intrinsic::ppc_altivec_vcmpgtsq:
10982 case Intrinsic::ppc_altivec_vcmpgtuq:
10983 if (!Subtarget.isISA3_1())
10985 switch (IntrinsicID) {
10988 case Intrinsic::ppc_altivec_vcmpequq:
10991 case Intrinsic::ppc_altivec_vcmpgtsq:
10994 case Intrinsic::ppc_altivec_vcmpgtuq:
11001 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11002 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11003 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11004 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11005 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11006 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11007 if (Subtarget.hasVSX()) {
11008 switch (IntrinsicID) {
11009 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11012 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11015 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11018 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11021 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11024 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11034 case Intrinsic::ppc_altivec_vcmpbfp:
11037 case Intrinsic::ppc_altivec_vcmpeqfp:
11040 case Intrinsic::ppc_altivec_vcmpequb:
11043 case Intrinsic::ppc_altivec_vcmpequh:
11046 case Intrinsic::ppc_altivec_vcmpequw:
11049 case Intrinsic::ppc_altivec_vcmpequd:
11050 if (Subtarget.hasP8Altivec())
11055 case Intrinsic::ppc_altivec_vcmpneb:
11056 case Intrinsic::ppc_altivec_vcmpneh:
11057 case Intrinsic::ppc_altivec_vcmpnew:
11058 case Intrinsic::ppc_altivec_vcmpnezb:
11059 case Intrinsic::ppc_altivec_vcmpnezh:
11060 case Intrinsic::ppc_altivec_vcmpnezw:
11061 if (Subtarget.hasP9Altivec())
11062 switch (IntrinsicID) {
11065 case Intrinsic::ppc_altivec_vcmpneb:
11068 case Intrinsic::ppc_altivec_vcmpneh:
11071 case Intrinsic::ppc_altivec_vcmpnew:
11074 case Intrinsic::ppc_altivec_vcmpnezb:
11077 case Intrinsic::ppc_altivec_vcmpnezh:
11080 case Intrinsic::ppc_altivec_vcmpnezw:
11087 case Intrinsic::ppc_altivec_vcmpgefp:
11090 case Intrinsic::ppc_altivec_vcmpgtfp:
11093 case Intrinsic::ppc_altivec_vcmpgtsb:
11096 case Intrinsic::ppc_altivec_vcmpgtsh:
11099 case Intrinsic::ppc_altivec_vcmpgtsw:
11102 case Intrinsic::ppc_altivec_vcmpgtsd:
11103 if (Subtarget.hasP8Altivec())
11108 case Intrinsic::ppc_altivec_vcmpgtub:
11111 case Intrinsic::ppc_altivec_vcmpgtuh:
11114 case Intrinsic::ppc_altivec_vcmpgtuw:
11117 case Intrinsic::ppc_altivec_vcmpgtud:
11118 if (Subtarget.hasP8Altivec())
11123 case Intrinsic::ppc_altivec_vcmpequq_p:
11124 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11125 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11126 if (!Subtarget.isISA3_1())
11128 switch (IntrinsicID) {
11131 case Intrinsic::ppc_altivec_vcmpequq_p:
11134 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11137 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11151 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11157 auto MapNodeWithSplatVector =
11158 [&](
unsigned Opcode,
11159 std::initializer_list<SDValue> ExtraOps = {}) -> SDValue {
11164 Ops.append(ExtraOps.begin(), ExtraOps.end());
11165 return DAG.
getNode(Opcode, dl, MVT::v16i8,
Ops);
11168 switch (IntrinsicID) {
11169 case Intrinsic::thread_pointer:
11171 if (Subtarget.isPPC64())
11175 case Intrinsic::ppc_rldimi: {
11176 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11177 SDValue Src =
Op.getOperand(1);
11178 APInt
Mask =
Op.getConstantOperandAPInt(4);
11180 return Op.getOperand(2);
11181 if (
Mask.isAllOnes())
11184 unsigned MB = 0, ME = 0;
11188 if (ME < 63 - SH) {
11191 }
else if (ME > 63 - SH) {
11197 {Op.getOperand(2), Src,
11198 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11199 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11203 case Intrinsic::ppc_rlwimi: {
11204 APInt
Mask =
Op.getConstantOperandAPInt(4);
11206 return Op.getOperand(2);
11207 if (
Mask.isAllOnes())
11210 unsigned MB = 0, ME = 0;
11214 PPC::RLWIMI, dl, MVT::i32,
11215 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11216 DAG.getTargetConstant(MB, dl, MVT::i32),
11217 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11221 case Intrinsic::ppc_bcdshift:
11222 return MapNodeWithSplatVector(PPCISD::BCDSHIFT, {
Op.getOperand(3)});
11223 case Intrinsic::ppc_bcdshiftround:
11224 return MapNodeWithSplatVector(PPCISD::BCDSHIFTROUND, {
Op.getOperand(3)});
11225 case Intrinsic::ppc_bcdtruncate:
11226 return MapNodeWithSplatVector(PPCISD::BCDTRUNC, {
Op.getOperand(3)});
11227 case Intrinsic::ppc_bcdunsignedtruncate:
11228 return MapNodeWithSplatVector(PPCISD::BCDUTRUNC);
11229 case Intrinsic::ppc_bcdunsignedshift:
11230 return MapNodeWithSplatVector(PPCISD::BCDUSHIFT);
11232 case Intrinsic::ppc_rlwnm: {
11233 if (
Op.getConstantOperandVal(3) == 0)
11235 unsigned MB = 0, ME = 0;
11240 {Op.getOperand(1), Op.getOperand(2),
11241 DAG.getTargetConstant(MB, dl, MVT::i32),
11242 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11246 case Intrinsic::ppc_mma_disassemble_acc: {
11247 if (Subtarget.isISAFuture()) {
11248 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11250 SDValue(DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes,
11255 SDValue Value2 = SDValue(WideVec.
getNode(), 1);
11259 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11260 Subtarget.isLittleEndian() ? Value2 :
Value,
11261 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11265 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11266 Subtarget.isLittleEndian() ? Value2 :
Value,
11267 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11271 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11272 Subtarget.isLittleEndian() ?
Value : Value2,
11273 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11277 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
11278 Subtarget.isLittleEndian() ?
Value : Value2,
11279 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11286 case Intrinsic::ppc_vsx_disassemble_pair: {
11288 SDValue WideVec =
Op.getOperand(1);
11289 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11291 WideVec = DAG.
getNode(PPCISD::XXMFACC, dl, MVT::v512i1, WideVec);
11294 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11295 SDValue Extract = DAG.
getNode(
11296 PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8, WideVec,
11297 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11305 case Intrinsic::ppc_build_dmr: {
11308 for (
int i = 1; i < 9; i += 2) {
11309 SDValue
Hi =
Op.getOperand(i);
11310 SDValue
Lo =
Op.getOperand(i + 1);
11316 DAG.
getNode(PPCISD::PAIR_BUILD, dl, MVT::v256i1, {Hi, Lo}));
11319 SDValue
Value = DMFInsert1024(Pairs, SDLoc(
Op), DAG);
11323 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11324 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11326 assert(Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11327 "Specify P of 0 or 1 for lower or upper 512 bytes");
11328 unsigned HiLo =
Idx->getSExtValue();
11332 Opcode = PPC::DMXXEXTFDMR512;
11333 Subx = PPC::sub_wacc_lo;
11335 Opcode = PPC::DMXXEXTFDMR512_HI;
11336 Subx = PPC::sub_wacc_hi;
11339 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11343 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11344 return SDValue(DAG.
getMachineNode(Opcode, dl, ReturnTypes, Subreg), 0);
11347 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11348 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11350 assert(Idx && (
Idx->getSExtValue() >= 0 ||
Idx->getSExtValue() <= 3) &&
11351 "Specify a dmr row pair 0-3");
11352 unsigned IdxVal =
Idx->getSExtValue();
11356 Subx = PPC::sub_dmrrowp0;
11359 Subx = PPC::sub_dmrrowp1;
11362 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11365 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11369 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11375 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11379 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11380 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11382 assert(Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11383 "Specify P of 0 or 1 for lower or upper 512 bytes");
11384 unsigned HiLo =
Idx->getSExtValue();
11388 Opcode = PPCISD::INST512;
11389 Subx = PPC::sub_wacc_lo;
11391 Opcode = PPCISD::INST512HI;
11392 Subx = PPC::sub_wacc_hi;
11394 SDValue Wacc = DAG.
getNode(Opcode, dl, MVT::v512i1,
Op.getOperand(2),
11397 return SDValue(DAG.
getMachineNode(PPC::INSERT_SUBREG, dl, MVT::v1024i1,
11398 Op.getOperand(1), Wacc, SubReg),
11402 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11403 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11405 assert(Idx && (
Idx->getSExtValue() >= 0 ||
Idx->getSExtValue() <= 3) &&
11406 "Specify a dmr row pair 0-3");
11407 unsigned IdxVal =
Idx->getSExtValue();
11411 Subx = PPC::sub_dmrrowp0;
11414 Subx = PPC::sub_dmrrowp1;
11417 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11420 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11426 DAG.
getNode(PPCISD::INST256, dl, MVT::v256i1,
Op.getOperand(2),
P);
11427 return SDValue(DAG.
getMachineNode(PPC::INSERT_SUBREG, dl, MVT::v1024i1,
11428 Op.getOperand(1), DMRRowp, SubReg),
11432 case Intrinsic::ppc_mma_xxmfacc:
11433 case Intrinsic::ppc_mma_xxmtacc: {
11435 if (!Subtarget.isISAFuture())
11441 SDValue WideVec =
Op.getOperand(1);
11446 case Intrinsic::ppc_unpack_longdouble: {
11448 assert(Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11449 "Argument of long double unpack must be 0 or 1!");
11452 Idx->getValueType(0)));
11455 case Intrinsic::ppc_compare_exp_lt:
11456 case Intrinsic::ppc_compare_exp_gt:
11457 case Intrinsic::ppc_compare_exp_eq:
11458 case Intrinsic::ppc_compare_exp_uo: {
11460 switch (IntrinsicID) {
11461 case Intrinsic::ppc_compare_exp_lt:
11464 case Intrinsic::ppc_compare_exp_gt:
11467 case Intrinsic::ppc_compare_exp_eq:
11470 case Intrinsic::ppc_compare_exp_uo:
11476 PPC::SELECT_CC_I4, dl, MVT::i32,
11477 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11478 Op.getOperand(1), Op.getOperand(2)),
11480 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11481 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11484 case Intrinsic::ppc_test_data_class: {
11485 EVT OpVT =
Op.getOperand(1).getValueType();
11486 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11487 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11498 SDValue TestDataClass =
11500 {Op.getOperand(2), Op.getOperand(1)}),
11502 if (Subtarget.isISA3_1()) {
11508 SDValue(DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
11509 TestDataClass, SubRegIdx),
11512 return DAG.
getNode(PPCISD::SETBC, dl, MVT::i32, CRBit);
11518 {TestDataClass, DAG.getConstant(1, dl, MVT::i32),
11519 DAG.getConstant(0, dl, MVT::i32),
11520 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11523 case Intrinsic::ppc_fnmsub: {
11524 EVT VT =
Op.getOperand(1).getValueType();
11525 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11530 return DAG.
getNode(PPCISD::FNMSUB, dl, VT,
Op.getOperand(1),
11531 Op.getOperand(2),
Op.getOperand(3));
11533 case Intrinsic::ppc_convert_f128_to_ppcf128:
11534 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11535 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11536 ? RTLIB::CONVERT_PPCF128_F128
11537 : RTLIB::CONVERT_F128_PPCF128;
11539 std::pair<SDValue, SDValue>
Result =
11540 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11544 case Intrinsic::ppc_maxfe:
11545 case Intrinsic::ppc_maxfl:
11546 case Intrinsic::ppc_maxfs:
11547 case Intrinsic::ppc_minfe:
11548 case Intrinsic::ppc_minfl:
11549 case Intrinsic::ppc_minfs: {
11550 EVT VT =
Op.getValueType();
11553 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11554 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11557 if (IntrinsicID == Intrinsic::ppc_minfe ||
11558 IntrinsicID == Intrinsic::ppc_minfl ||
11559 IntrinsicID == Intrinsic::ppc_minfs)
11562 SDValue Res =
Op.getOperand(
I);
11580 SDValue Tmp = DAG.
getNode(PPCISD::VCMP, dl,
Op.getOperand(2).getValueType(),
11581 Op.getOperand(1),
Op.getOperand(2),
11592 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11593 SDValue CompNode = DAG.
getNode(PPCISD::VCMP_rec, dl, VTs,
Ops);
11600 switch (
Op.getConstantOperandVal(1)) {
11605 Bitx = PPC::sub_eq;
11606 SetOp = PPCISD::SETBC;
11611 Bitx = PPC::sub_eq;
11612 SetOp = PPCISD::SETBCR;
11617 Bitx = PPC::sub_lt;
11618 SetOp = PPCISD::SETBC;
11623 Bitx = PPC::sub_lt;
11624 SetOp = PPCISD::SETBCR;
11628 SDValue GlueOp = CompNode.
getValue(1);
11629 if (Subtarget.isISA3_1()) {
11631 SDValue CR6Reg = DAG.
getRegister(PPC::CR6, MVT::i32);
11633 SDValue(DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::i1,
11634 CR6Reg, SubRegIdx, GlueOp),
11636 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11664 switch (
Op.getConstantOperandVal(ArgStart)) {
11665 case Intrinsic::ppc_cfence: {
11666 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11667 SDValue Val =
Op.getOperand(ArgStart + 1);
11669 if (Ty == MVT::i128) {
11674 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11677 Opcode,
DL, MVT::Other,
11682 case Intrinsic::ppc_disassemble_dmr: {
11684 "llvm.ppc.disassemble.dmr must carry a chain argument.");
11685 return DAG.
getStore(
Op.getOperand(0),
DL,
Op.getOperand(ArgStart + 2),
11686 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11697 if (!Subtarget.isPPC64())
11700 if (Subtarget.hasP9Vector()) {
11707 int VectorIndex = 0;
11708 if (Subtarget.isLittleEndian())
11716 SDValue
Input =
Op.getOperand(0);
11718 auto CreateRotateInsert =
11719 [&](
unsigned Opcode, MVT VT, SDValue Dest, SDValue Src,
unsigned RotAmt,
11720 unsigned MaskBegin,
11721 std::optional<unsigned> MaskEnd = std::nullopt) -> SDValue {
11725 if (MaskEnd.has_value())
11732 auto Swap32 = [&](SDValue Val32) -> SDValue {
11737 CreateRotateInsert(PPC::RLWIMI, MVT::i32, Rot, Val32, 24, 0, 7);
11739 return CreateRotateInsert(PPC::RLWIMI, MVT::i32,
Swap, Val32, 24, 16, 23);
11752 return CreateRotateInsert(PPC::RLDIMI, MVT::i64, HiSwap, LoSwap, 32, 0);
11760 "Expecting an atomic compare-and-swap here.");
11763 EVT MemVT = AtomicNode->getMemoryVT();
11767 SDValue CmpOp =
Op.getOperand(2);
11781 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11782 Ops.push_back(AtomicNode->getOperand(i));
11784 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11785 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11787 (MemVT == MVT::i8) ? PPCISD::ATOMIC_CMP_SWAP_8 : PPCISD::ATOMIC_CMP_SWAP_16;
11794 EVT MemVT =
N->getMemoryVT();
11796 "Expect quadword atomic operations");
11798 unsigned Opc =
N->getOpcode();
11803 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11806 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11807 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11808 Ops.push_back(
N->getOperand(
I));
11810 Ops, MemVT,
N->getMemOperand());
11817 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11824 SDVTList Tys = DAG.
getVTList(MVT::Other);
11827 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11833 Ops.push_back(ValLo);
11834 Ops.push_back(ValHi);
11835 Ops.push_back(
N->getOperand(2));
11837 N->getMemOperand());
11849 enum DataClassMask {
11851 DC_NEG_INF = 1 << 4,
11852 DC_POS_INF = 1 << 5,
11853 DC_NEG_ZERO = 1 << 2,
11854 DC_POS_ZERO = 1 << 3,
11855 DC_NEG_SUBNORM = 1,
11856 DC_POS_SUBNORM = 1 << 1,
11859 EVT VT =
Op.getValueType();
11861 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11862 : VT == MVT::f64 ? PPC::XSTSTDCDP
11873 return DAG.
getNOT(Dl, Rev, MVT::i1);
11880 TestOp, Dl, MVT::i32,
11882 DC_NEG_ZERO | DC_POS_ZERO |
11883 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11889 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11895 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11900 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11913 bool IsQuiet = Mask &
fcQNan;
11919 if (VT == MVT::f128) {
11923 QuietMask = 0x8000;
11924 }
else if (VT == MVT::f64) {
11925 if (Subtarget.isPPC64()) {
11936 QuietMask = 0x80000;
11937 }
else if (VT == MVT::f32) {
11939 QuietMask = 0x400000;
11955 unsigned NativeMask = 0;
11957 NativeMask |= DC_NAN;
11959 NativeMask |= DC_NEG_INF;
11961 NativeMask |= DC_POS_INF;
11963 NativeMask |= DC_NEG_ZERO;
11965 NativeMask |= DC_POS_ZERO;
11967 NativeMask |= DC_NEG_SUBNORM;
11969 NativeMask |= DC_POS_SUBNORM;
11972 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11974 TestOp, Dl, MVT::i32,
11983 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11984 SDValue
LHS =
Op.getOperand(0);
11985 uint64_t RHSC =
Op.getConstantOperandVal(1);
11988 if (
LHS.getValueType() == MVT::ppcf128) {
12012 bool Future = Subtarget.isISAFuture();
12015 "Mask predication not supported");
12018 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
12019 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
12021 SDValue
Ops[] = {VPLD->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
12023 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
12026 VPLD->getMemoryVT(), VPLD->getMemOperand());
12033 "Mask predication not supported");
12038 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
12039 bool Future = Subtarget.isISAFuture();
12040 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
12043 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
12046 SDVTList Tys = DAG.
getVTList(MVT::Other);
12049 VPST->getMemoryVT(), VPST->getMemOperand());
12055 SDValue Acc =
Op.getOperand(0);
12056 SDValue Op1 =
Op.getOperand(1);
12057 SDValue Op2 =
Op.getOperand(2);
12060 "Unexpected partial reduction");
12071 SDValue Ones = DAG.
getConstant(1, dl, MVT::v16i8);
12081 SDValue Op0 =
Op.getOperand(0);
12083 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
12085 int64_t
IntVal =
Op.getConstantOperandVal(0);
12086 if (IntVal >= -16 && IntVal <= 15)
12092 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
12099 MMOMetadata(RLI.AAInfo, RLI.Ranges));
12102 PPCISD::LD_SPLAT, dl, DAG.
getVTList(MVT::v4i32, MVT::Other),
Ops,
12106 return Bits.getValue(0);
12122 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12127 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12133 SDValue
Store = DAG.
getStore(Store2, dl, Val, FIdx, MachinePointerInfo());
12135 MachinePointerInfo());
12142 return DAG.
getLoad(
Op.getValueType(), dl,
Store, FIdx, MachinePointerInfo());
12148 "Should only be called for ISD::INSERT_VECTOR_ELT");
12152 EVT VT =
Op.getValueType();
12154 SDValue
V1 =
Op.getOperand(0);
12155 SDValue V2 =
Op.getOperand(1);
12157 if (VT == MVT::v2f64 &&
C)
12160 if (Subtarget.hasP9Vector()) {
12169 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12171 SDValue BitcastVector = DAG.
getBitcast(MVT::v4i32,
V1);
12172 SDValue BitcastLoad = DAG.
getBitcast(MVT::i32, V2);
12173 SDValue InsVecElt =
12175 BitcastLoad,
Op.getOperand(2));
12176 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12180 if (Subtarget.isISA3_1()) {
12181 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12185 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12186 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12196 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12197 SDValue Mtvsrz = DAG.
getNode(PPCISD::MTVSRZ, dl, VT, V2);
12199 unsigned InsertAtElement =
C->getZExtValue();
12200 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12201 if (Subtarget.isLittleEndian()) {
12202 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12204 return DAG.
getNode(PPCISD::VECINSERT, dl, VT,
V1, Mtvsrz,
12214 SDValue LoadChain = LN->
getChain();
12216 EVT VT =
Op.getValueType();
12217 bool IsV1024i1 = VT == MVT::v1024i1;
12218 bool IsV2048i1 = VT == MVT::v2048i1;
12222 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12224 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12225 "Dense Math support required.");
12226 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12231 SDValue IntrinID = DAG.
getConstant(Intrinsic::ppc_vsx_lxvp, dl, MVT::i32);
12232 SDValue LoadOps[] = {LoadChain, IntrinID,
BasePtr};
12235 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12236 MachineMemOperand *NewMMO =
12244 DAG.
getVTList(MVT::v256i1, MVT::Other),
12245 LoadOps, MVT::v256i1, NewMMO);
12250 if (Subtarget.isLittleEndian()) {
12251 std::reverse(Loads.
begin(), Loads.
end());
12252 std::reverse(LoadChains.
begin(), LoadChains.
end());
12256 SDValue
Value = DMFInsert1024(Loads, dl, DAG);
12264 SDValue Dmr1Value = DMFInsert1024(MoreLoads, dl, DAG);
12270 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12272 SDValue DmrPValue = SDValue(
12273 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12282 DAG.
getNode(PPCISD::INST512, dl, MVT::v512i1, Pairs[0], Pairs[1]);
12285 DAG.
getNode(PPCISD::INST512HI, dl, MVT::v512i1, Pairs[2], Pairs[3]);
12289 return SDValue(DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1,
12290 {RC, Lo, LoSub, Hi, HiSub}),
12298 SDValue LoadChain = LN->
getChain();
12300 EVT VT =
Op.getValueType();
12302 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12303 return LowerDMFVectorLoad(
Op, DAG);
12305 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12309 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12310 "Type unsupported without MMA");
12311 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12312 "Type unsupported without paired vector support");
12316 if (VT == MVT::v256i1 && Subtarget.isISAFuture())
12325 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12327 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12336 if (Subtarget.isLittleEndian()) {
12337 std::reverse(Loads.
begin(), Loads.
end());
12338 std::reverse(LoadChains.
begin(), LoadChains.
end());
12342 DAG.
getNode(VT == MVT::v512i1 ? PPCISD::ACC_BUILD : PPCISD::PAIR_BUILD,
12344 SDValue RetOps[] = {
Value, TF};
12353 SDValue StoreChain = SN->
getChain();
12358 bool IsV1024i1 = VT == MVT::v1024i1;
12359 bool IsV2048i1 = VT == MVT::v2048i1;
12363 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12365 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12366 "Dense Math support required.");
12367 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12369 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12372 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12377 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12381 MachineSDNode *ExtNode =
12383 Values.push_back(SDValue(ExtNode, 0));
12384 Values.push_back(SDValue(ExtNode, 1));
12385 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12386 Values.push_back(SDValue(ExtNode, 0));
12387 Values.push_back(SDValue(ExtNode, 1));
12391 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12397 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12403 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12408 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12413 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12418 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12422 MachineSDNode *ExtNode =
12423 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12424 Values.push_back(SDValue(ExtNode, 0));
12425 Values.push_back(SDValue(ExtNode, 1));
12427 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12428 Values.push_back(SDValue(ExtNode, 0));
12429 Values.push_back(SDValue(ExtNode, 1));
12430 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12431 Values.push_back(SDValue(ExtNode, 0));
12432 Values.push_back(SDValue(ExtNode, 1));
12434 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12435 Values.push_back(SDValue(ExtNode, 0));
12436 Values.push_back(SDValue(ExtNode, 1));
12439 if (Subtarget.isLittleEndian())
12442 SDVTList Tys = DAG.
getVTList(MVT::Other);
12444 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12448 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12449 MachineMemOperand *NewMMO =
12458 MVT::v256i1, NewMMO);
12470 SDValue StoreChain = SN->
getChain();
12474 EVT StoreVT =
Value.getValueType();
12476 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12477 return LowerDMFVectorStore(
Op, DAG);
12479 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12483 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12484 "Type unsupported without MMA");
12485 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12486 "Type unsupported without paired vector support");
12490 if (StoreVT == MVT::v256i1 && Subtarget.isISAFuture() &&
12498 unsigned NumVecs = 2;
12499 if (StoreVT == MVT::v512i1) {
12500 if (Subtarget.isISAFuture()) {
12501 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12503 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12505 Value = SDValue(ExtNode, 0);
12506 Value2 = SDValue(ExtNode, 1);
12511 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12512 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 -
Idx :
Idx;
12514 if (Subtarget.isISAFuture()) {
12515 VecNum = Subtarget.isLittleEndian() ? 1 - (
Idx % 2) : (
Idx % 2);
12516 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
12517 Idx > 1 ? Value2 :
Value,
12520 Elt = DAG.
getNode(PPCISD::EXTRACT_VSX_REG, dl, MVT::v16i8,
Value,
12524 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12538 if (
Op.getValueType() == MVT::v4i32) {
12539 SDValue
LHS =
Op.getOperand(0),
RHS =
Op.getOperand(1);
12555 LHS,
RHS, DAG, dl, MVT::v4i32);
12558 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12563 }
else if (
Op.getValueType() == MVT::v16i8) {
12564 SDValue
LHS =
Op.getOperand(0),
RHS =
Op.getOperand(1);
12565 bool isLittleEndian = Subtarget.isLittleEndian();
12569 LHS,
RHS, DAG, dl, MVT::v8i16);
12574 LHS,
RHS, DAG, dl, MVT::v8i16);
12582 for (
unsigned i = 0; i != 8; ++i) {
12583 if (isLittleEndian) {
12585 Ops[i*2+1] = 2*i+16;
12588 Ops[i*2+1] = 2*i+1+16;
12591 if (isLittleEndian)
12601 bool IsStrict =
Op->isStrictFPOpcode();
12602 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12603 !Subtarget.hasP9Vector())
12613 "Should only be called for ISD::FP_EXTEND");
12617 if (
Op.getValueType() != MVT::v2f64 ||
12618 Op.getOperand(0).getValueType() != MVT::v2f32)
12622 SDValue Op0 =
Op.getOperand(0);
12630 "Node should have 2 operands with second one being a constant!");
12642 int DWord =
Idx >> 1;
12645 if (Subtarget.isLittleEndian())
12648 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64,
12654 SDValue NewLoad[2];
12662 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12664 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12665 LD->getMemoryVT(),
LD->getMemOperand());
12670 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewOp,
12675 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12677 PPCISD::LD_VSX_LH, dl, DAG.
getVTList(MVT::v4f32, MVT::Other), LoadOps,
12678 LD->getMemoryVT(),
LD->getMemOperand());
12679 return DAG.
getNode(PPCISD::FP_EXTEND_HALF, dl, MVT::v2f64, NewLd,
12690 if (STI.useCRBits())
12707 PPCISD::ADDE,
DL, DAG.
getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12708 if (STI.useCRBits())
12716 SDNode *
N =
Op.getNode();
12717 EVT VT =
N->getValueType(0);
12718 EVT CarryType =
N->getValueType(1);
12719 unsigned Opc =
N->getOpcode();
12721 Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12723 N->getOperand(0),
N->getOperand(1));
12735 SDNode *
N =
Op.getNode();
12736 unsigned Opc =
N->getOpcode();
12737 EVT VT =
N->getValueType(0);
12738 EVT CarryType =
N->getValueType(1);
12739 SDValue CarryOp =
N->getOperand(2);
12741 Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12747 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12759 SDValue
LHS =
Op.getOperand(0);
12760 SDValue
RHS =
Op.getOperand(1);
12761 EVT VT =
Op.getNode()->getValueType(0);
12774 SDValue OverflowTrunc =
12785 SDValue
LHS =
Op.getOperand(0);
12786 SDValue
RHS =
Op.getOperand(1);
12787 EVT VT =
Op.getNode()->getValueType(0);
12793 SDValue EqvXY = DAG.
getNOT(dl, XorXY, VT);
12798 SDValue OverflowInSign = DAG.
getNode(
ISD::AND, dl, VT, EqvXY, SumXorX);
12805 SDValue OverflowTrunc =
12817 SDValue
LHS =
Op.getOperand(0);
12818 SDValue
RHS =
Op.getOperand(1);
12819 EVT OpVT =
LHS.getValueType();
12820 EVT VT =
Op.getValueType();
12835 unsigned Opcode = PPCISD::SUBC;
12841 SDValue SubLHS =
RHS.getOperand(0);
12842 SDValue SubRHS =
RHS.getOperand(1);
12845 Opcode = PPCISD::ADDC;
12852 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12859 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12864 SDValue ZeroOrNeg1 = DAG.
getNode(PPCISD::SUBE,
DL, VTs, Res, Res, CA0);
12879 EVT OpVT =
A.getValueType();
12880 EVT ResVT =
Op.getValueType();
12885 if (Subtarget.isPPC64() && OpVT != MVT::i64) {
12895 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12896 SDValue SubC = DAG.
getNode(PPCISD::SUBC,
DL, VTs,
B,
A);
12900 SDValue SubE1 = DAG.
getNode(PPCISD::SUBE,
DL, VTs,
A,
B, CA0);
12904 SDValue ResPair = DAG.
getNode(PPCISD::SUBE,
DL, VTs, Diff, SubE1, CA1);
12921 SDValue
LHS =
Op.getOperand(0);
12922 SDValue
RHS =
Op.getOperand(1);
12923 EVT VT =
LHS.getValueType();
12924 EVT ResVT =
Op.getValueType();
12927 if (Subtarget.isISA3_0())
12931 bool Is64BitCmp = (VT == MVT::i64);
12936 bool Use64BitOps = Subtarget.isPPC64();
12939 unsigned CmpOpc = Is64BitCmp ? PPC::CMPD : PPC::CMPW;
12943 SDValue CR7Reg = DAG.
getRegister(PPC::CR7, MVT::i32);
12950 unsigned MFOCRFOpc = Use64BitOps ? PPC::MFOCRF8 : PPC::MFOCRF;
12951 EVT MFVT = Use64BitOps ? MVT::i64 : MVT::i32;
12962 unsigned RLWinmOpc = Use64BitOps ? PPC::RLWINM8 : PPC::RLWINM;
12968 SDValue LTBit = SDValue(DAG.
getMachineNode(RLWinmOpc,
DL, MFVT, LTOps), 0);
12974 SDValue GTBit = SDValue(DAG.
getMachineNode(RLWinmOpc,
DL, MFVT, GTOps), 0);
12980 unsigned SubOpc = Use64BitOps ? PPC::SUBF8 : PPC::SUBF;
12994 switch (
Op.getOpcode()) {
13015 return LowerSSUBO(
Op, DAG);
13017 return LowerSADDO(
Op, DAG);
13029 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
13050 return LowerSET_ROUNDING(
Op, DAG);
13057 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
13058 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
13070 return LowerFP_ROUND(
Op, DAG);
13084 return LowerINTRINSIC_VOID(
Op, DAG);
13086 return LowerBSWAP(
Op, DAG);
13088 return LowerATOMIC_CMP_SWAP(
Op, DAG);
13090 return LowerATOMIC_LOAD_STORE(
Op, DAG);
13092 return LowerIS_FPCLASS(
Op, DAG);
13095 return LowerADDSUBO(
Op, DAG);
13098 return LowerADDSUBO_CARRY(
Op, DAG);
13100 return LowerUCMP(
Op, DAG);
13102 return LowerABDU(
Op, DAG);
13104 return LowerSCMP(
Op, DAG);
13110 if (
Op->getFlags().hasNoFPExcept())
13114 return LowerVP_LOAD(
Op, DAG);
13115 case ISD::VP_STORE:
13116 return LowerVP_STORE(
Op, DAG);
13118 return LowerPartialReduce(
Op, DAG);
13126 switch (
N->getOpcode()) {
13128 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
13145 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
13148 assert(
N->getValueType(0) == MVT::i1 &&
13149 "Unexpected result type for CTR decrement intrinsic");
13151 N->getValueType(0));
13161 switch (
N->getConstantOperandVal(0)) {
13162 case Intrinsic::ppc_pack_longdouble:
13164 N->getOperand(2),
N->getOperand(1)));
13166 case Intrinsic::ppc_maxfe:
13167 case Intrinsic::ppc_minfe:
13168 case Intrinsic::ppc_fnmsub:
13169 case Intrinsic::ppc_convert_f128_to_ppcf128:
13176 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
13179 EVT VT =
N->getValueType(0);
13181 if (VT == MVT::i64) {
13194 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
13198 Results.push_back(LoweredValue);
13199 if (
N->isStrictFPOpcode())
13204 if (!
N->getValueType(0).isVector())
13237 return Builder.CreateIntrinsicWithoutFolding(Id, {});
13243 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
13245 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13246 "Only 8/16/32/64-bit atomic loads supported");
13252 IntID = Intrinsic::ppc_lbarx;
13253 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13256 IntID = Intrinsic::ppc_lharx;
13257 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13260 IntID = Intrinsic::ppc_lwarx;
13263 IntID = Intrinsic::ppc_ldarx;
13267 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
13269 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13280 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13281 "Only 8/16/32/64-bit atomic loads supported");
13287 IntID = Intrinsic::ppc_stbcx;
13288 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13291 IntID = Intrinsic::ppc_sthcx;
13292 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13295 IntID = Intrinsic::ppc_stwcx;
13298 IntID = Intrinsic::ppc_stdcx;
13302 if (SZ == 8 || SZ == 16)
13303 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13305 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13307 return Builder.CreateXor(
Call, Builder.getInt32(1));
13330 return Builder.CreateIntrinsicWithoutFolding(Intrinsic::ppc_cfence,
13339 return !Subtarget.fenceKeepsReservation();
13344 unsigned BinOpcode,
13345 unsigned CmpOpcode,
13346 unsigned CmpPred)
const {
13351 unsigned AtomicSize =
MI.getOperand(3).getImm();
13353 auto LoadMnemonic = PPC::LDARX;
13354 auto StoreMnemonic = PPC::STDCX;
13355 switch (AtomicSize) {
13359 LoadMnemonic = PPC::LBARX;
13360 StoreMnemonic = PPC::STBCX;
13361 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13364 LoadMnemonic = PPC::LHARX;
13365 StoreMnemonic = PPC::STHCX;
13366 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13369 LoadMnemonic = PPC::LWARX;
13370 StoreMnemonic = PPC::STWCX;
13373 LoadMnemonic = PPC::LDARX;
13374 StoreMnemonic = PPC::STDCX;
13382 if (CmpOpcode == PPC::CMPW && (AtomicSize == 1 || AtomicSize == 2))
13393 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13395 F->insert(It, loopMBB);
13397 F->insert(It, loop2MBB);
13398 F->insert(It, exitMBB);
13404 Register TmpReg = (!BinOpcode) ? incr :
13405 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13406 : &PPC::GPRCRegClass);
13431 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13436 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13438 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13439 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13440 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13470 switch(
MI.getOpcode()) {
13474 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13475 &
MI.getMF()->getRegInfo());
13499 case PPC::EXTSB8_32_64:
13500 case PPC::EXTSB8_rec:
13501 case PPC::EXTSB_rec:
13504 case PPC::EXTSH8_32_64:
13505 case PPC::EXTSH8_rec:
13506 case PPC::EXTSH_rec:
13508 case PPC::EXTSWSLI:
13509 case PPC::EXTSWSLI_32_64:
13510 case PPC::EXTSWSLI_32_64_rec:
13511 case PPC::EXTSWSLI_rec:
13512 case PPC::EXTSW_32:
13513 case PPC::EXTSW_32_64:
13514 case PPC::EXTSW_32_64_rec:
13515 case PPC::EXTSW_rec:
13518 case PPC::SRAWI_rec:
13519 case PPC::SRAW_rec:
13529 unsigned OpIdx,
bool IsByte,
13534 bool IsSignExtended =
13537 if (!IsSignExtended) {
13538 Register ValueReg =
RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13540 TII->get(IsByte ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13542 MI.getOperand(OpIdx).setReg(ValueReg);
13548 unsigned CmpOpcode,
unsigned CmpPred)
const {
13552 assert(!Subtarget.hasPartwordAtomics() &&
13553 "Assumes that part-word atomics are not available");
13561 const bool is8bit =
MI.getOperand(3).getImm() == 1;
13562 if (CmpOpcode == PPC::CMPW)
13570 bool is64bit = Subtarget.isPPC64();
13571 bool isLittleEndian = Subtarget.isLittleEndian();
13572 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13583 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13585 F->insert(It, loopMBB);
13587 F->insert(It, loop2MBB);
13588 F->insert(It, exitMBB);
13594 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13597 Register PtrReg = RegInfo.createVirtualRegister(RC);
13598 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13600 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13601 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13602 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13603 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13604 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13605 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13606 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13607 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13608 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13609 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13612 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13639 if (ptrA != ZeroReg) {
13640 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13641 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13649 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13650 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
13653 .
addImm(is8bit ? 28 : 27);
13654 if (!isLittleEndian)
13655 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13657 .
addImm(is8bit ? 24 : 16);
13659 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13664 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13674 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13678 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13683 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13687 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13690 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13697 Register SReg = RegInfo.createVirtualRegister(GPRC);
13698 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13702 unsigned ValueReg = SReg;
13703 unsigned CmpReg = Incr2Reg;
13704 if (CmpOpcode == PPC::CMPW) {
13705 ValueReg = RegInfo.createVirtualRegister(GPRC);
13706 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13709 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13710 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13712 ValueReg = ValueSReg;
13744 .
addImm(is8bit ? 24 : 16)
13765 Register DstReg =
MI.getOperand(0).getReg();
13767 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13768 Register mainDstReg =
MRI.createVirtualRegister(RC);
13769 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13772 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13773 "Invalid Pointer Size!");
13821 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13822 Register BufReg =
MI.getOperand(1).getReg();
13824 if (Subtarget.is64BitELFABI()) {
13837 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13839 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13842 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13865 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13868 if (Subtarget.isPPC64()) {
13886 TII->get(PPC::PHI), DstReg)
13890 MI.eraseFromParent();
13904 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13905 "Invalid Pointer Size!");
13908 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13911 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13912 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13926 Register BufReg =
MI.getOperand(0).getReg();
13931 if (PVT == MVT::i64) {
13943 if (PVT == MVT::i64) {
13955 if (PVT == MVT::i64) {
13967 if (PVT == MVT::i64) {
13979 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13989 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13992 MI.eraseFromParent();
14008 "Unexpected stack alignment");
14012 unsigned StackProbeSize =
14015 StackProbeSize &= ~(StackAlign - 1);
14016 return StackProbeSize ? StackProbeSize : StackAlign;
14028 const bool isPPC64 = Subtarget.isPPC64();
14060 MF->
insert(MBBIter, TestMBB);
14061 MF->
insert(MBBIter, BlockMBB);
14062 MF->
insert(MBBIter, TailMBB);
14067 Register DstReg =
MI.getOperand(0).getReg();
14068 Register NegSizeReg =
MI.getOperand(1).getReg();
14070 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14071 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14072 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14078 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
14080 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
14086 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
14087 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
14089 .
addDef(ActualNegSizeReg)
14091 .
add(
MI.getOperand(2))
14092 .
add(
MI.getOperand(3));
14098 .
addReg(ActualNegSizeReg);
14101 int64_t NegProbeSize = -(int64_t)ProbeSize;
14103 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14105 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14107 .
addImm(NegProbeSize >> 16);
14111 .
addImm(NegProbeSize & 0xFFFF);
14118 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14120 .
addReg(ActualNegSizeReg)
14122 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14126 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14129 .
addReg(ActualNegSizeReg);
14138 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
14139 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
14164 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
14166 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
14167 MaxCallFrameSizeReg)
14168 .
add(
MI.getOperand(2))
14169 .
add(
MI.getOperand(3));
14170 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
14172 .
addReg(MaxCallFrameSizeReg);
14178 MBB->addSuccessor(TestMBB);
14181 MI.eraseFromParent();
14183 ++NumDynamicAllocaProbed;
14191static bool IsSelect(
unsigned Opcode,
bool CheckOnlyCC =
false) {
14194 case PPC::SELECT_CC_I4:
14195 case PPC::SELECT_CC_I8:
14196 case PPC::SELECT_CC_F4:
14197 case PPC::SELECT_CC_F8:
14198 case PPC::SELECT_CC_F16:
14199 case PPC::SELECT_CC_VRRC:
14200 case PPC::SELECT_CC_VSFRC:
14201 case PPC::SELECT_CC_VSSRC:
14202 case PPC::SELECT_CC_VSRC:
14203 case PPC::SELECT_CC_SPE4:
14204 case PPC::SELECT_CC_SPE:
14207 case PPC::SELECT_I4:
14208 case PPC::SELECT_I8:
14209 case PPC::SELECT_F4:
14210 case PPC::SELECT_F8:
14211 case PPC::SELECT_F16:
14212 case PPC::SELECT_SPE:
14213 case PPC::SELECT_SPE4:
14214 case PPC::SELECT_VRRC:
14215 case PPC::SELECT_VSFRC:
14216 case PPC::SELECT_VSSRC:
14217 case PPC::SELECT_VSRC:
14218 return !CheckOnlyCC;
14234 assert(
IsSelect(
MI.getOpcode()) &&
"Instruction must be a SELECT variant");
14237 if (Subtarget.hasISEL() &&
14238 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14239 MI.getOpcode() == PPC::SELECT_CC_I8 ||
14240 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
14242 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
14243 MI.getOpcode() == PPC::SELECT_CC_I8)
14244 Cond.push_back(
MI.getOperand(4));
14247 Cond.push_back(
MI.getOperand(1));
14250 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
14251 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
14252 MI.eraseFromParent();
14265 F->insert(It, copy0MBB);
14266 F->insert(It, sinkMBB);
14274 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14290 .
addImm(
MI.getOperand(4).getImm())
14291 .
addReg(
MI.getOperand(1).getReg())
14295 .
addReg(
MI.getOperand(1).getReg())
14305 .
addReg(
MI.getOperand(3).getReg())
14307 .
addReg(
MI.getOperand(2).getReg())
14309 MI.eraseFromParent();
14324 loop1MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14325 loop2MBB =
F->CreateMachineBasicBlock(LLVM_BB);
14326 exitMBB =
F->CreateMachineBasicBlock(LLVM_BB);
14327 F->insert(It, loop1MBB);
14328 F->insert(It, loop2MBB);
14329 F->insert(It, exitMBB);
14364 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14366 unsigned LoadMnemonic = PPC::LDARX;
14367 unsigned StoreMnemonic = PPC::STDCX;
14368 switch (
MI.getOpcode()) {
14371 case PPC::ATOMIC_CMP_SWAP_I8:
14372 LoadMnemonic = PPC::LBARX;
14373 StoreMnemonic = PPC::STBCX;
14374 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14376 case PPC::ATOMIC_CMP_SWAP_I16:
14377 LoadMnemonic = PPC::LHARX;
14378 StoreMnemonic = PPC::STHCX;
14379 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14381 case PPC::ATOMIC_CMP_SWAP_I32:
14382 LoadMnemonic = PPC::LWARX;
14383 StoreMnemonic = PPC::STWCX;
14385 case PPC::ATOMIC_CMP_SWAP_I64:
14386 LoadMnemonic = PPC::LDARX;
14387 StoreMnemonic = PPC::STDCX;
14395 Register oldval =
MI.getOperand(3).getReg();
14396 Register newval =
MI.getOperand(4).getReg();
14410 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14478 bool is64bit = Subtarget.isPPC64();
14480 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14485 Register oldval =
MI.getOperand(3).getReg();
14486 Register newval =
MI.getOperand(4).getReg();
14494 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14499 return RegInfo.createVirtualRegister(RC);
14503 Register Shift1Reg = createVReg(GPRC);
14504 Register ShiftReg = isLittleEndian ? Shift1Reg : createVReg(GPRC);
14505 Register NewVal2Reg = createVReg(GPRC);
14506 Register NewVal3Reg = createVReg(GPRC);
14507 Register OldVal2Reg = createVReg(GPRC);
14508 Register OldVal3Reg = createVReg(GPRC);
14509 Register MaskReg = createVReg(GPRC);
14510 Register Mask2Reg = createVReg(GPRC);
14511 Register Mask3Reg = createVReg(GPRC);
14512 Register Tmp2Reg = createVReg(GPRC);
14513 Register Tmp4Reg = createVReg(GPRC);
14514 Register TmpDestReg = createVReg(GPRC);
14515 Register TmpReg = createVReg(GPRC);
14516 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14517 Register CrReg = createVReg(&PPC::CRRCRegClass);
14521 if (ptrA != ZeroReg) {
14522 Ptr1Reg = createVReg(RC);
14523 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14530 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14531 .
addReg(Ptr1Reg, {}, is64bit ? PPC::sub_32 : 0)
14534 .
addImm(is8bit ? 28 : 27);
14535 if (!isLittleEndian)
14536 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14538 .
addImm(is8bit ? 24 : 16);
14540 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14545 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14552 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14555 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14562 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14566 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14569 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14572 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14582 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14603 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14648 switch (
MI.getOpcode()) {
14649 case TargetOpcode::STACKMAP:
14651 case TargetOpcode::PATCHPOINT:
14657 if (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls())
14661 case PPC::EH_SjLj_SetJmp32:
14662 case PPC::EH_SjLj_SetJmp64:
14665 case PPC::EH_SjLj_LongJmp32:
14666 case PPC::EH_SjLj_LongJmp64:
14669 case PPC::ReadTB: {
14685 F->insert(It, readMBB);
14686 F->insert(It, sinkMBB);
14697 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14705 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14707 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14719 case PPC::ATOMIC_LOAD_ADD_NOWP:
14722 case PPC::ATOMIC_LOAD_ADD:
14725 case PPC::ATOMIC_LOAD_ADD_I64:
14728 case PPC::ATOMIC_LOAD_AND_NOWP:
14731 case PPC::ATOMIC_LOAD_AND:
14734 case PPC::ATOMIC_LOAD_AND_I64:
14737 case PPC::ATOMIC_LOAD_OR_NOWP:
14740 case PPC::ATOMIC_LOAD_OR:
14743 case PPC::ATOMIC_LOAD_OR_I64:
14746 case PPC::ATOMIC_LOAD_XOR_NOWP:
14749 case PPC::ATOMIC_LOAD_XOR:
14752 case PPC::ATOMIC_LOAD_XOR_I64:
14755 case PPC::ATOMIC_LOAD_NAND_NOWP:
14758 case PPC::ATOMIC_LOAD_NAND:
14761 case PPC::ATOMIC_LOAD_NAND_I64:
14764 case PPC::ATOMIC_LOAD_SUB_NOWP:
14767 case PPC::ATOMIC_LOAD_SUB:
14770 case PPC::ATOMIC_LOAD_SUB_I64:
14773 case PPC::ATOMIC_LOAD_MIN_NOWP:
14776 case PPC::ATOMIC_LOAD_MIN:
14779 case PPC::ATOMIC_LOAD_MIN_I64:
14782 case PPC::ATOMIC_LOAD_MAX_NOWP:
14785 case PPC::ATOMIC_LOAD_MAX:
14788 case PPC::ATOMIC_LOAD_MAX_I64:
14791 case PPC::ATOMIC_LOAD_UMIN_NOWP:
14794 case PPC::ATOMIC_LOAD_UMIN:
14797 case PPC::ATOMIC_LOAD_UMIN_I64:
14800 case PPC::ATOMIC_LOAD_UMAX_NOWP:
14803 case PPC::ATOMIC_LOAD_UMAX:
14806 case PPC::ATOMIC_LOAD_UMAX_I64:
14809 case PPC::ATOMIC_SWAP_NOWP:
14812 case PPC::ATOMIC_SWAP:
14813 case PPC::ATOMIC_SWAP_I64:
14816 case PPC::ATOMIC_CMP_SWAP_I32:
14817 case PPC::ATOMIC_CMP_SWAP_I64:
14818 case PPC::ATOMIC_CMP_SWAP_I8:
14819 case PPC::ATOMIC_CMP_SWAP_I16: {
14821 bool useHardware =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14822 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14823 (Subtarget.hasPartwordAtomics() &&
14824 (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14825 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16));
14833 case PPC::FADDrtz: {
14843 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14858 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14868 case PPC::ANDI_rec_1_EQ_BIT:
14869 case PPC::ANDI_rec_1_GT_BIT:
14870 case PPC::ANDI_rec_1_EQ_BIT8:
14871 case PPC::ANDI_rec_1_GT_BIT8: {
14872 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14873 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14876 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14877 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14880 Register Dest = RegInfo.createVirtualRegister(
14881 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14885 .
addReg(
MI.getOperand(1).getReg())
14888 MI.getOperand(0).getReg())
14889 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14892 case PPC::TCHECK_RET: {
14895 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14898 MI.getOperand(0).getReg())
14902 case PPC::TBEGIN_RET: {
14904 unsigned Imm =
MI.getOperand(1).getImm();
14907 MI.getOperand(0).getReg())
14911 case PPC::SETRNDi: {
14913 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14916 if (
MRI.use_empty(OldFPSCRReg))
14917 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14919 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14930 unsigned Mode =
MI.getOperand(1).getImm();
14931 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14935 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14940 case PPC::SETRND: {
14948 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14949 if (Subtarget.hasDirectMove()) {
14950 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14954 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14957 if (RC == &PPC::F8RCRegClass) {
14959 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14960 "Unsupported RegClass.");
14962 StoreOp = PPC::STFD;
14966 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14967 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14968 "Unsupported RegClass.");
15001 Register OldFPSCRReg =
MI.getOperand(0).getReg();
15004 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
15016 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
15018 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
15020 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
15021 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
15026 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
15027 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
15032 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
15033 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
15039 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
15040 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
15051 case PPC::SETFLM: {
15055 Register OldFPSCRReg =
MI.getOperand(0).getReg();
15056 if (
MRI.use_empty(OldFPSCRReg))
15057 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
15059 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
15062 Register NewFPSCRReg =
MI.getOperand(1).getReg();
15070 case PPC::PROBED_ALLOCA_32:
15071 case PPC::PROBED_ALLOCA_64:
15074 case PPC::SPLIT_QUADWORD: {
15081 .
addUse(Src, {}, PPC::sub_gp8_x1);
15084 .
addUse(Src, {}, PPC::sub_gp8_x0);
15087 case PPC::LQX_PSEUDO:
15088 case PPC::STQX_PSEUDO: {
15094 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
15100 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
15101 :
TII->get(PPC::STQ))
15111 MI.eraseFromParent();
15124 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
15127 return RefinementSteps;
15134 EVT VT =
Op.getValueType();
15137 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
15142 SDValue FTSQRT = DAG.
getNode(PPCISD::FTSQRT,
DL, MVT::i32,
Op, Flags);
15155 return SDValue(DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG,
DL, MVT::i1,
15161PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
15164 EVT VT =
Op.getValueType();
15165 if (VT != MVT::f64 &&
15166 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
15169 return DAG.
getNode(PPCISD::FSQRT, SDLoc(
Op), VT,
Op);
15173 int Enabled,
int &RefinementSteps,
15174 bool &UseOneConstNR,
15175 bool Reciprocal)
const {
15177 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
15178 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
15179 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15180 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15186 UseOneConstNR = !Subtarget.needsTwoConstNR();
15187 return DAG.
getNode(PPCISD::FRSQRTE, SDLoc(Operand), VT, Operand);
15194 int &RefinementSteps)
const {
15196 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
15197 (VT == MVT::f64 && Subtarget.hasFRE()) ||
15198 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
15199 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
15202 return DAG.
getNode(PPCISD::FRE, SDLoc(Operand), VT, Operand);
15218 switch (Subtarget.getCPUDirective()) {
15245 unsigned Bytes,
int Dist,
15259 if (FS != BFS || FS != (
int)Bytes)
return false;
15264 int64_t Offset1 = 0, Offset2 = 0;
15267 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
15277 if (isGA1 && isGA2 && GV1 == GV2)
15278 return Offset1 == (Offset2 + Dist*Bytes);
15285 unsigned Bytes,
int Dist,
15288 EVT VT = LS->getMemoryVT();
15295 switch (
N->getConstantOperandVal(1)) {
15296 default:
return false;
15297 case Intrinsic::ppc_altivec_lvx:
15298 case Intrinsic::ppc_altivec_lvxl:
15299 case Intrinsic::ppc_vsx_lxvw4x:
15300 case Intrinsic::ppc_vsx_lxvw4x_be:
15303 case Intrinsic::ppc_vsx_lxvd2x:
15304 case Intrinsic::ppc_vsx_lxvd2x_be:
15307 case Intrinsic::ppc_altivec_lvebx:
15310 case Intrinsic::ppc_altivec_lvehx:
15313 case Intrinsic::ppc_altivec_lvewx:
15323 switch (
N->getConstantOperandVal(1)) {
15324 default:
return false;
15325 case Intrinsic::ppc_altivec_stvx:
15326 case Intrinsic::ppc_altivec_stvxl:
15327 case Intrinsic::ppc_vsx_stxvw4x:
15330 case Intrinsic::ppc_vsx_stxvd2x:
15333 case Intrinsic::ppc_vsx_stxvw4x_be:
15336 case Intrinsic::ppc_vsx_stxvd2x_be:
15339 case Intrinsic::ppc_altivec_stvebx:
15342 case Intrinsic::ppc_altivec_stvehx:
15345 case Intrinsic::ppc_altivec_stvewx:
15362 SDValue Chain = LD->getChain();
15363 EVT VT = LD->getMemoryVT();
15372 while (!Queue.empty()) {
15373 SDNode *ChainNext = Queue.pop_back_val();
15374 if (!Visited.
insert(ChainNext).second)
15381 if (!Visited.
count(ChainLD->getChain().getNode()))
15382 Queue.push_back(ChainLD->getChain().getNode());
15384 for (
const SDUse &O : ChainNext->
ops())
15385 if (!Visited.
count(O.getNode()))
15386 Queue.push_back(O.getNode());
15388 LoadRoots.
insert(ChainNext);
15399 for (
SDNode *
I : LoadRoots) {
15400 Queue.push_back(
I);
15402 while (!Queue.empty()) {
15403 SDNode *LoadRoot = Queue.pop_back_val();
15404 if (!Visited.
insert(LoadRoot).second)
15416 Queue.push_back(U);
15447 auto Final = Shifted;
15458 DAGCombinerInfo &DCI)
const {
15461 SelectionDAG &DAG = DCI.DAG;
15466 if (!DCI.isAfterLegalizeDAG())
15471 for (
const SDNode *U :
N->users())
15476 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15480 if (OpSize <
Size) {
15498 DAGCombinerInfo &DCI)
const {
15499 SelectionDAG &DAG = DCI.DAG;
15502 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15513 N->getValueType(0) != MVT::i1)
15516 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15517 N->getOperand(0).getValueType() != MVT::i64)
15527 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15538 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15561 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15562 N->getOperand(0).getOpcode() !=
ISD::OR &&
15563 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15573 N->getOperand(1).getOpcode() !=
ISD::AND &&
15574 N->getOperand(1).getOpcode() !=
ISD::OR &&
15575 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15586 SmallPtrSet<SDNode *, 16> Visited;
15588 for (
unsigned i = 0; i < 2; ++i) {
15592 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15604 while (!BinOps.
empty()) {
15612 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15646 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15650 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15651 if (User !=
N && !Visited.
count(User))
15660 if (
User->getOperand(0) == Inputs[i])
15663 if (
User->getOperand(0) == Inputs[i] ||
15664 User->getOperand(1) == Inputs[i])
15670 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15671 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15672 if (User !=
N && !Visited.
count(User))
15681 if (
User->getOperand(0) == PromOps[i])
15684 if (
User->getOperand(0) == PromOps[i] ||
15685 User->getOperand(1) == PromOps[i])
15692 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15701 std::list<HandleSDNode> PromOpHandles;
15702 for (
auto &PromOp : PromOps)
15703 PromOpHandles.emplace_back(PromOp);
15710 while (!PromOpHandles.empty()) {
15711 SDValue PromOp = PromOpHandles.back().getValue();
15712 PromOpHandles.pop_back();
15721 PromOpHandles.emplace_front(PromOp);
15735 default:
C = 0;
break;
15748 PromOpHandles.emplace_front(PromOp);
15755 for (
unsigned i = 0; i < 2; ++i)
15765 return N->getOperand(0);
15769 return SDValue(
N, 0);
15773 DAGCombinerInfo &DCI)
const {
15774 SelectionDAG &DAG = DCI.DAG;
15791 if (
N->getValueType(0) != MVT::i32 &&
15792 N->getValueType(0) != MVT::i64)
15795 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15796 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15799 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15800 N->getOperand(0).getOpcode() !=
ISD::OR &&
15801 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15808 SmallPtrSet<SDNode *, 16> Visited;
15812 while (!BinOps.
empty()) {
15820 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15846 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15851 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15856 if (User !=
N && !Visited.
count(User))
15862 if (
User->getOperand(0) == Inputs[i])
15863 SelectTruncOp[0].
insert(std::make_pair(User,
15864 User->getOperand(0).getValueType()));
15866 if (
User->getOperand(0) == Inputs[i])
15867 SelectTruncOp[0].
insert(std::make_pair(User,
15868 User->getOperand(0).getValueType()));
15869 if (
User->getOperand(1) == Inputs[i])
15870 SelectTruncOp[1].
insert(std::make_pair(User,
15871 User->getOperand(1).getValueType()));
15876 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15878 if (User !=
N && !Visited.
count(User))
15884 if (
User->getOperand(0) == PromOps[i])
15885 SelectTruncOp[0].
insert(std::make_pair(User,
15886 User->getOperand(0).getValueType()));
15888 if (
User->getOperand(0) == PromOps[i])
15889 SelectTruncOp[0].
insert(std::make_pair(User,
15890 User->getOperand(0).getValueType()));
15891 if (
User->getOperand(1) == PromOps[i])
15892 SelectTruncOp[1].
insert(std::make_pair(User,
15893 User->getOperand(1).getValueType()));
15898 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15899 bool ReallyNeedsExt =
false;
15903 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15908 Inputs[i].getOperand(0).getValueSizeInBits();
15909 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15914 OpBits-PromBits))) ||
15917 (OpBits-(PromBits-1)))) {
15918 ReallyNeedsExt =
true;
15926 std::list<HandleSDNode> PromOpHandles;
15927 for (
auto &PromOp : PromOps)
15928 PromOpHandles.emplace_back(PromOp);
15932 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15939 SDValue InSrc = Inputs[i].getOperand(0);
15957 while (!PromOpHandles.empty()) {
15958 SDValue PromOp = PromOpHandles.back().
getValue();
15959 PromOpHandles.pop_back();
15963 default:
C = 0;
break;
15976 PromOpHandles.emplace_front(PromOp);
15986 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15988 PromOpHandles.emplace_front(PromOp);
15996 for (
unsigned i = 0; i < 2; ++i) {
16014 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
16015 if (SI0 != SelectTruncOp[0].
end())
16017 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
16018 if (SI1 != SelectTruncOp[1].
end())
16027 if (!ReallyNeedsExt)
16028 return N->getOperand(0);
16035 N->getValueSizeInBits(0), PromBits),
16036 dl,
N->getValueType(0)));
16039 "Invalid extension type");
16042 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
16052 auto isValidForConvert = [IsPPC64](
SDValue &Operand) {
16061 const APInt &Val =
C->getAPIntValue();
16067 if (IsPPC64 && Val.
ult(1ULL << 16))
16081 if (LoadNode->isVolatile())
16102 return (isValidForConvert(
LHS) && isValidForConvert(
RHS));
16112 "CC mus be ISD::SETNE or ISD::SETEQ");
16114 auto getV16i8Load = [&](
const SDValue &Operand) {
16132 LoadNode->getBasePtr(), NewMMO);
16173 SDValue LHSVec = getV16i8Load(
N->getOperand(0));
16174 SDValue RHSVec = getV16i8Load(
N->getOperand(1));
16177 DAG.
getConstant(Intrinsic::ppc_altivec_vcmpequb_p,
DL, MVT::i32);
16180 IntrID, CRSel, LHSVec, RHSVec);
16183 return DAG.
getSetCC(
DL,
N->getValueType(0), PredResult,
16201 auto IsAndWithOne = [](
SDValue &V) {
16212 auto IsCompareWithZero = [](
SDValue &V) {
16219 return (IsAndWithOne(
LHS) && IsCompareWithZero(
RHS)) ||
16220 (IsAndWithOne(
RHS) && IsCompareWithZero(
LHS));
16237 auto MakeXor1 = [&](
SDValue V) {
16238 EVT VT = V.getValueType();
16245 return MakeXor1(
LHS);
16248 return MakeXor1(
RHS);
16265 DAGCombinerInfo &DCI)
const {
16266 if (Subtarget.isISA3_1())
16269 EVT VT =
N->getValueType(0);
16270 if (VT != MVT::i32 && (VT != MVT::i64 || !Subtarget.isPPC64()))
16286 SelectionDAG &DAG = DCI.DAG;
16288 EVT XVT =
X.getValueType();
16292 MVT OpVT = Subtarget.isPPC64() ? MVT::i64 : MVT::i32;
16304 SDValue Sube = DAG.
getNode(PPCISD::SUBE, dl, DAG.
getVTList(OpVT, MVT::i32),
16305 Addc, Addc, Carry);
16308 if (OpVT == MVT::i64 && VT == MVT::i32)
16315 DAGCombinerInfo &DCI)
const {
16317 "Should be called with a SETCC node");
16326 SDValue
LHS =
N->getOperand(0);
16327 SDValue
RHS =
N->getOperand(1);
16339 SelectionDAG &DAG = DCI.DAG;
16340 EVT VT =
N->getValueType(0);
16341 EVT OpVT =
LHS.getValueType();
16359 if (Subtarget.hasAltivec() &&
16364 return DAGCombineTruncBoolExt(
N, DCI);
16371 Op.getValueType() == MVT::f64;
16383combineElementTruncationToVectorTruncation(
SDNode *
N,
16384 DAGCombinerInfo &DCI)
const {
16386 "Should be called with a BUILD_VECTOR node");
16388 SelectionDAG &DAG = DCI.DAG;
16391 SDValue FirstInput =
N->getOperand(0);
16393 "The input operand must be an fp-to-int conversion.");
16398 if (FirstConversion == PPCISD::FCTIDZ ||
16399 FirstConversion == PPCISD::FCTIDUZ ||
16400 FirstConversion == PPCISD::FCTIWZ ||
16401 FirstConversion == PPCISD::FCTIWUZ) {
16402 bool IsSplat =
true;
16403 bool Is32Bit = FirstConversion == PPCISD::FCTIWZ ||
16404 FirstConversion == PPCISD::FCTIWUZ;
16407 EVT TargetVT =
N->getValueType(0);
16408 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16409 SDValue NextOp =
N->getOperand(i);
16410 if (NextOp.
getOpcode() != PPCISD::MFVSR)
16413 if (NextConversion != FirstConversion)
16421 if (
N->getOperand(i) != FirstInput)
16432 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
16433 SDValue
In =
N->getOperand(i).getOperand(0);
16443 Ops.push_back(Trunc);
16446 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
16450 if (FirstConversion == PPCISD::FCTIDZ ||
16451 FirstConversion == PPCISD::FCTIWZ)
16456 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
16458 return DAG.
getNode(Opcode, dl, TargetVT, BV);
16476 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
16480 if (FullVal == BasePattern)
16481 return std::make_tuple(Uim,
uint8_t{0});
16484 if (FullVal ==
APInt(128, 1))
16485 return std::make_tuple(Uim,
uint8_t{127});
16487 return std::nullopt;
16507 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
16511 EVT VT =
Op.getValueType();
16512 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
16526 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
16536 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
16540 uint64_t ElemValue =
C->getZExtValue();
16544 ElemValue &= ((1ULL << ElemBits) - 1);
16548 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
16551 APInt ElemAPInt(128, ElemValue);
16552 ElemAPInt <<= BitPos;
16555 FullVal |= ElemAPInt;
16562 const auto &[Uim, ShiftAmount] = *UIMOpt;
16566 if (ShiftAmount == 0) {
16568 SDValue LxvkqInstr =
16571 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
16572 LxvkqInstr.
dump());
16576 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
16582 SDValue ShiftAmountVec =
16587 SDValue ShiftVec = SDValue(
16588 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
16591 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
16607 "Should be called with a BUILD_VECTOR node");
16612 if (!
N->getValueType(0).getVectorElementType().isByteSized())
16615 bool InputsAreConsecutiveLoads =
true;
16616 bool InputsAreReverseConsecutive =
true;
16617 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
16618 SDValue FirstInput =
N->getOperand(0);
16619 bool IsRoundOfExtLoad =
false;
16629 N->getNumOperands() == 1)
16632 if (!IsRoundOfExtLoad)
16637 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
16639 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
16642 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
16648 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
16659 InputsAreConsecutiveLoads =
false;
16661 InputsAreReverseConsecutive =
false;
16664 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
16669 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
16670 "The loads cannot be both consecutive and reverse consecutive.");
16674 if (InputsAreConsecutiveLoads) {
16675 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16679 ReturnSDVal = WideLoad;
16680 }
else if (InputsAreReverseConsecutive) {
16682 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16687 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16695 for (
auto *LD : InputLoads)
16697 return ReturnSDVal;
16708 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16714 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16716 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16718 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16719 CorrectElems = CorrectElems >> 8;
16720 Elems = Elems >> 8;
16727 EVT VT =
N->getValueType(0);
16731 Input.getValueType().getVectorElementType(),
16765 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16791 Elems = Elems << 8;
16800 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16801 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16808 int TgtElemArrayIdx;
16809 int InputSize =
Input.getValueType().getScalarSizeInBits();
16810 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16811 if (InputSize + OutputSize == 40)
16812 TgtElemArrayIdx = 0;
16813 else if (InputSize + OutputSize == 72)
16814 TgtElemArrayIdx = 1;
16815 else if (InputSize + OutputSize == 48)
16816 TgtElemArrayIdx = 2;
16817 else if (InputSize + OutputSize == 80)
16818 TgtElemArrayIdx = 3;
16819 else if (InputSize + OutputSize == 96)
16820 TgtElemArrayIdx = 4;
16824 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16826 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16827 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16828 if (Elems != CorrectElems) {
16844 if (
N->getValueType(0) != MVT::v1i128)
16847 SDValue Operand =
N->getOperand(0);
16854 EVT MemoryType = LD->getMemoryVT();
16858 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16859 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16862 if (!ValidLDType ||
16868 LD->getChain(), LD->getBasePtr(),
16872 DAG.
getVTList(MVT::v1i128, MVT::Other),
16873 LoadOps, MemoryType, LD->getMemOperand());
16877 DAGCombinerInfo &DCI)
const {
16879 "Should be called with a BUILD_VECTOR node");
16881 SelectionDAG &DAG = DCI.DAG;
16884 if (!Subtarget.hasVSX())
16891 if (FirstInput.
getOpcode() == PPCISD::MFVSR) {
16892 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16907 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16916 if (Subtarget.isISA3_1()) {
16922 if (
N->getValueType(0) != MVT::v2f64)
16933 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16944 if (!Ext1Op || !Ext2Op)
16953 if (FirstElem == 0 && SecondElem == 1)
16954 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16955 else if (FirstElem == 2 && SecondElem == 3)
16956 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16962 PPCISD::SINT_VEC_TO_FP : PPCISD::UINT_VEC_TO_FP;
16963 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16968 DAGCombinerInfo &DCI)
const {
16971 "Need an int -> FP conversion node here");
16976 SelectionDAG &DAG = DCI.DAG;
16982 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16984 if (!
Op.getOperand(0).getValueType().isSimple())
16986 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16987 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16990 SDValue FirstOperand(
Op.getOperand(0));
16991 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16992 (FirstOperand.getValueType() == MVT::i8 ||
16993 FirstOperand.getValueType() == MVT::i16);
16994 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16996 bool DstDouble =
Op.getValueType() == MVT::f64;
16997 unsigned ConvOp =
Signed ?
16998 (DstDouble ? PPCISD::FCFID : PPCISD::FCFIDS) :
16999 (DstDouble ? PPCISD::FCFIDU : PPCISD::FCFIDUS);
17000 SDValue WidthConst =
17004 SDValue
Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
17007 Ops, MVT::i8, LDN->getMemOperand());
17012 SDValue ExtOps[] = { Ld, WidthConst };
17013 SDValue Ext = DAG.
getNode(PPCISD::VEXTS, dl, MVT::f64, ExtOps);
17014 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
17016 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
17024 if (
Op.getOperand(0).getValueType() == MVT::i32)
17028 "UINT_TO_FP is supported only with FPCVT");
17032 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
17037 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
17044 Subtarget.hasFPCVT()) ||
17046 SDValue Src =
Op.getOperand(0).getOperand(0);
17047 if (Src.getValueType() == MVT::f32) {
17049 DCI.AddToWorklist(Src.getNode());
17050 }
else if (Src.getValueType() != MVT::f64) {
17059 SDValue Tmp = DAG.
getNode(FCTOp, dl, MVT::f64, Src);
17060 SDValue
FP = DAG.
getNode(FCFOp, dl, FCFTy, Tmp);
17062 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
17065 DCI.AddToWorklist(
FP.getNode());
17089 switch (
N->getOpcode()) {
17094 Chain = LD->getChain();
17095 Base = LD->getBasePtr();
17096 MMO = LD->getMemOperand();
17115 MVT VecTy =
N->getValueType(0).getSimpleVT();
17123 Chain =
Load.getValue(1);
17125 PPCISD::XXSWAPD, dl, DAG.
getVTList(MVT::v2f64, MVT::Other), Chain,
Load);
17129 if (VecTy != MVT::v2f64) {
17134 N,
Swap.getValue(1));
17156 switch (
N->getOpcode()) {
17161 Chain = ST->getChain();
17162 Base = ST->getBasePtr();
17163 MMO = ST->getMemOperand();
17183 SDValue Src =
N->getOperand(SrcOpnd);
17184 MVT VecTy = Src.getValueType().getSimpleVT();
17187 if (VecTy != MVT::v2f64) {
17193 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
17195 Chain =
Swap.getValue(1);
17199 StoreOps, VecTy, MMO);
17206 DAGCombinerInfo &DCI)
const {
17209 unsigned Opcode =
N->getOperand(1).getOpcode();
17211 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
17215 &&
"Not a FP_TO_INT Instruction!");
17218 EVT Op1VT =
N->getOperand(1).getValueType();
17221 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
17225 bool ValidTypeForStoreFltAsInt =
17226 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
17227 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
17230 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
17233 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
17241 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
17256 bool PrevElemFromFirstVec = Mask[0] < NumElts;
17257 for (
int i = 1, e = Mask.size(); i < e; i++) {
17258 if (PrevElemFromFirstVec && Mask[i] < NumElts)
17260 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
17262 PrevElemFromFirstVec = !PrevElemFromFirstVec;
17273 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
17274 FirstOp =
Op.getOperand(i);
17280 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
17281 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
17291 Op =
Op.getOperand(0);
17307 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
17308 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
17310 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
17312 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
17313 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
17314 int Idx = ShuffV[
I];
17315 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
17316 ShuffV[
I] += LHSEltFixup;
17317 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
17318 ShuffV[
I] += RHSEltFixup;
17329 SDLoc dl(OrigSToV);
17332 "Expecting a SCALAR_TO_VECTOR here");
17345 "Cannot produce a permuted scalar_to_vector for one element vector");
17347 unsigned ResultInElt = NumElts / 2;
17349 NewMask[ResultInElt] = Idx->getZExtValue();
17353 return DAG.
getNode(PPCISD::SCALAR_TO_VECTOR_PERMUTED, dl, VT,
17358 int HalfVec,
int LHSLastElementDefined,
17359 int RHSLastElementDefined) {
17360 for (
int Index : ShuffV) {
17364 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
17365 (Index > LHSLastElementDefined))
17368 if ((RHSLastElementDefined >= 0) &&
17369 (Index > HalfVec + RHSLastElementDefined))
17376 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
17377 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
17393 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
17394 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
17397 if (SToVPermuted.
getValueType() != VecShuffOperandType)
17398 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
17399 return SToVPermuted;
17419 int NumElts =
LHS.getValueType().getVectorNumElements();
17420 SDValue Res(SVN, 0);
17422 bool IsLittleEndian = Subtarget.isLittleEndian();
17429 if (!Subtarget.hasDirectMove())
17449 SmallVector<int, 16> ShuffV(Mask);
17452 if (SToVLHS || SToVRHS) {
17455 int ShuffleNumElts = ShuffV.
size();
17456 int HalfVec = ShuffleNumElts / 2;
17462 unsigned LHSNumValidElts = HalfVec;
17463 unsigned RHSNumValidElts = HalfVec;
17468 int LHSFirstElt = 0;
17469 int RHSFirstElt = ShuffleNumElts;
17470 int LHSLastElt = -1;
17471 int RHSLastElt = -1;
17479 int LHSScalarSize = 0;
17480 int RHSScalarSize = 0;
17483 if (!IsLittleEndian && LHSScalarSize >= 64)
17488 if (!IsLittleEndian && RHSScalarSize >= 64)
17491 if (LHSScalarSize != 0)
17493 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
17494 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
17495 if (RHSScalarSize != 0)
17497 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
17498 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
17509 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
17510 LHSNumValidElts, RHSNumValidElts, Subtarget);
17520 SDValue TheSplat = IsLittleEndian ?
RHS :
LHS;
17536 if (IsLittleEndian) {
17539 if (Mask[0] < NumElts)
17540 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17544 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
17549 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17553 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
17558 if (Mask[0] < NumElts)
17559 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
17563 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
17568 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
17572 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
17582 if (IsLittleEndian)
17591 DAGCombinerInfo &DCI)
const {
17593 "Not a reverse memop pattern!");
17595 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
17598 auto I =
Mask.rbegin();
17599 auto E =
Mask.rend();
17601 for (;
I !=
E; ++
I) {
17609 SelectionDAG &DAG = DCI.DAG;
17612 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
17618 if (!Subtarget.hasP9Vector())
17621 if(!IsElementReverse(SVN))
17628 for (SDUse &Use : LSBase->
uses())
17629 if (
Use.getResNo() == 0 &&
17636 PPCISD::LOAD_VEC_BE, dl, DAG.
getVTList(VT, MVT::Other), LoadOps,
17651 PPCISD::STORE_VEC_BE, dl, DAG.
getVTList(MVT::Other), StoreOps,
17660 if (IntrinsicID == Intrinsic::ppc_stdcx)
17662 else if (IntrinsicID == Intrinsic::ppc_stwcx)
17664 else if (IntrinsicID == Intrinsic::ppc_sthcx)
17666 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17675 if (
N->getOpcode() == PPCISD::ADDC &&
N->hasAnyUseOfValue(1)) {
17679 if (
LHS->getOpcode() == PPCISD::ADDE &&
17690 if (
N->getOpcode() == PPCISD::SUBE) {
17696 if (
LHS ==
RHS &&
LHS.getOpcode() == PPCISD::ADDC) {
17699 if (AddcLHS.
getOpcode() == PPCISD::ADDE &&
17721 SDValue CmpLHS =
N->getOperand(0);
17722 SDValue CmpRHS =
N->getOperand(1);
17723 SDValue TrueVal =
N->getOperand(2);
17724 SDValue FalseVal =
N->getOperand(3);
17738 if (FalseVal.getOpcode() !=
ISD::SRL || !FalseVal.hasOneUse())
17741 SDValue ShiftVal = FalseVal.getOperand(0);
17742 SDValue ShiftAmt = FalseVal.getOperand(1);
17746 if (!ShiftConst || !ShiftConst->getAPIntValue().isMinSignedValue())
17773 if (CtlzArg != CmpLHS)
17781 DAG.
getNode(PPCISD::SRL,
DL, FalseVal.getValueType(), ShiftVal, ShiftAmt);
17828 auto isZeroOrOne = [=](
SDValue &V) {
17830 V.getConstantOperandVal(0) == Intrinsic::ppc_test_data_class)
17835 if (!isZeroOrOne(NonNullConstant))
17845 EVT VType =
N->getValueType(0);
17849 return NewNonNullConstant;
17868 EVT XorVT =
N->getValueType(0);
17869 if ((XorVT != MVT::i32 && XorVT != MVT::i64))
17877 if (!XorConst || !XorConst->
isOne()) {
17879 if (!XorConst || !XorConst->
isOne())
17886 if (!
LHS.hasOneUse())
17894 SelectNode =
LHS.getOperand(0);
17908 if (MachineOpc != PPC::SELECT_CC_I4 && MachineOpc != PPC::SELECT_CC_I8)
17918 if (!ConstOp1 || !ConstOp2)
17922 if (!((ConstOp1->
isOne() && ConstOp2->
isZero()) ||
17931 MachineOpc = (XorVT == MVT::i32) ? PPC::SELECT_CC_I4 : PPC::SELECT_CC_I8;
17933 bool ConstOp1IsOne = ConstOp1->
isOne();
17936 {SelectNode.getOperand(0),
17937 DAG.getConstant(ConstOp1IsOne ? 0 : 1, DL, XorVT),
17938 DAG.getConstant(ConstOp1IsOne ? 1 : 0, DL, XorVT),
17939 SelectNode.getOperand(3)}),
17947 switch (
N->getOpcode()) {
17950 return combineADD(
N, DCI);
17982 return combineSHL(
N, DCI);
17984 return combineSRA(
N, DCI);
17986 return combineSRL(
N, DCI);
17988 return combineMUL(
N, DCI);
17990 case PPCISD::FNMSUB:
17991 return combineFMALike(
N, DCI);
17994 return N->getOperand(0);
17998 return N->getOperand(0);
18004 return N->getOperand(0);
18015 N->getValueType(0) == MVT::i64 && N0.
getValueType() == MVT::i32 &&
18023 if (
SDValue SECC = combineSignExtendSetCC(
N, DCI))
18032 return DAGCombineExtBoolTrunc(
N, DCI);
18034 return combineTRUNCATE(
N, DCI);
18036 if (
SDValue CSCC = combineSetCC(
N, DCI))
18042 return DAGCombineTruncBoolExt(
N, DCI);
18045 return combineFPToIntToFP(
N, DCI);
18054 EVT Op1VT =
N->getOperand(1).getValueType();
18055 unsigned Opcode =
N->getOperand(1).getOpcode();
18059 SDValue Val = combineStoreFPToInt(
N, DCI);
18073 N->getOperand(1).getNode()->hasOneUse() &&
18074 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
18075 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
18083 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
18090 if (Op1VT.
bitsGT(mVT)) {
18095 if (Op1VT == MVT::i64)
18100 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
18120 ST->getBasePtr(), ST->getOffset(), MemVT,
18121 ST->getMemOperand(), ST->getAddressingMode(),
18125 return ST->isUnindexed()
18134 if (Subtarget.needsSwapsForVSXMemOps() &&
18135 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
18136 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
18143 EVT VT = LD->getValueType(0);
18149 if (Subtarget.needsSwapsForVSXMemOps() &&
18150 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
18151 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
18162 auto ReplaceTwoFloatLoad = [&]() {
18163 if (VT != MVT::i64)
18178 if (!LD->hasNUsesOfValue(2, 0))
18181 auto UI = LD->user_begin();
18182 while (UI.getUse().getResNo() != 0) ++UI;
18184 while (UI.getUse().getResNo() != 0) ++UI;
18185 SDNode *RightShift = *UI;
18193 if (RightShift->getOpcode() !=
ISD::SRL ||
18195 RightShift->getConstantOperandVal(1) != 32 ||
18196 !RightShift->hasOneUse())
18199 SDNode *Trunc2 = *RightShift->user_begin();
18209 Bitcast->getValueType(0) != MVT::f32)
18215 if (Subtarget.isLittleEndian())
18221 SDValue BasePtr = LD->getBasePtr();
18222 if (LD->isIndexed()) {
18224 "Non-pre-inc AM on PPC?");
18232 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
18233 LD->getPointerInfo(), LD->getAlign(),
18234 MMOFlags, LD->getAAInfo());
18240 LD->getPointerInfo().getWithOffset(4),
18243 if (LD->isIndexed()) {
18257 if (ReplaceTwoFloatLoad())
18260 EVT MemVT = LD->getMemoryVT();
18263 if (LD->isUnindexed() && VT.
isVector() &&
18266 !Subtarget.hasP8Vector() &&
18267 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
18268 VT == MVT::v4f32))) &&
18269 LD->getAlign() < ABIAlignment) {
18271 SDValue Chain = LD->getChain();
18272 SDValue Ptr = LD->getBasePtr();
18273 bool isLittleEndian = Subtarget.isLittleEndian();
18300 MVT PermCntlTy, PermTy, LDTy;
18301 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18302 : Intrinsic::ppc_altivec_lvsl;
18303 IntrLD = Intrinsic::ppc_altivec_lvx;
18304 IntrPerm = Intrinsic::ppc_altivec_vperm;
18305 PermCntlTy = MVT::v16i8;
18306 PermTy = MVT::v4i32;
18325 SDValue BaseLoadOps[] = { Chain, LDXIntID, Ptr };
18329 BaseLoadOps, LDTy, BaseMMO);
18338 int IncValue = IncOffset;
18355 SDValue ExtraLoadOps[] = { Chain, LDXIntID, Ptr };
18359 ExtraLoadOps, LDTy, ExtraMMO);
18370 if (isLittleEndian)
18372 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
18375 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
18378 Perm = Subtarget.hasAltivec()
18393 bool isLittleEndian = Subtarget.isLittleEndian();
18394 unsigned IID =
N->getConstantOperandVal(0);
18395 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
18396 : Intrinsic::ppc_altivec_lvsl);
18397 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
18404 .zext(
Add.getScalarValueSizeInBits()))) {
18405 SDNode *BasePtr =
Add->getOperand(0).getNode();
18406 for (
SDNode *U : BasePtr->users()) {
18408 U->getConstantOperandVal(0) == IID) {
18419 SDNode *BasePtr =
Add->getOperand(0).getNode();
18420 for (
SDNode *U : BasePtr->users()) {
18423 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
18429 V->getConstantOperandVal(0) == IID) {
18441 (IID == Intrinsic::ppc_altivec_vmaxsw ||
18442 IID == Intrinsic::ppc_altivec_vmaxsh ||
18443 IID == Intrinsic::ppc_altivec_vmaxsb)) {
18446 if ((
V1.getSimpleValueType() == MVT::v4i32 ||
18447 V1.getSimpleValueType() == MVT::v8i16 ||
18448 V1.getSimpleValueType() == MVT::v16i8) &&
18453 V1.getOperand(1) == V2) {
18474 switch (
N->getConstantOperandVal(1)) {
18477 case Intrinsic::ppc_altivec_vsum4sbs:
18478 case Intrinsic::ppc_altivec_vsum4shs:
18479 case Intrinsic::ppc_altivec_vsum4ubs: {
18486 APInt APSplatBits, APSplatUndef;
18487 unsigned SplatBitSize;
18490 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
18491 !Subtarget.isLittleEndian());
18493 if (BVNIsConstantSplat && APSplatBits == 0)
18498 case Intrinsic::ppc_vsx_lxvw4x:
18499 case Intrinsic::ppc_vsx_lxvd2x:
18502 if (Subtarget.needsSwapsForVSXMemOps())
18510 if (Subtarget.needsSwapsForVSXMemOps()) {
18511 switch (
N->getConstantOperandVal(1)) {
18514 case Intrinsic::ppc_vsx_stxvw4x:
18515 case Intrinsic::ppc_vsx_stxvd2x:
18524 bool Is64BitBswapOn64BitTgt =
18525 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
18527 N->getOperand(0).hasOneUse();
18528 if (IsSingleUseNormalLd &&
18529 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
18530 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
18541 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
18542 MVT::i64 : MVT::i32, MVT::Other),
18543 Ops, LD->getMemoryVT(), LD->getMemOperand());
18547 if (
N->getValueType(0) == MVT::i16)
18564 !IsSingleUseNormalLd)
18569 if (!LD->isSimple())
18571 SDValue BasePtr = LD->getBasePtr();
18573 LD->getPointerInfo(), LD->getAlign());
18578 LD->getMemOperand(), 4, 4);
18582 if (Subtarget.isLittleEndian())
18588 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
18597 if (!
N->getOperand(0).hasOneUse() &&
18598 !
N->getOperand(1).hasOneUse() &&
18599 !
N->getOperand(2).hasOneUse()) {
18602 SDNode *VCMPrecNode =
nullptr;
18604 SDNode *LHSN =
N->getOperand(0).getNode();
18606 if (
User->getOpcode() == PPCISD::VCMP_rec &&
18610 VCMPrecNode =
User;
18622 SDNode *FlagUser =
nullptr;
18624 FlagUser ==
nullptr; ++UI) {
18625 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
18638 return SDValue(VCMPrecNode, 0);
18649 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
18660 auto RHSAPInt = RHS->getAsAPIntVal();
18661 if (!RHSAPInt.isIntN(64))
18664 unsigned Val = RHSAPInt.getZExtValue();
18665 auto isImpossibleCompare = [&]() {
18668 if (Val != 0 && Val != 1) {
18670 return N->getOperand(0);
18673 N->getOperand(0),
N->getOperand(4));
18678 unsigned StoreWidth = 0;
18681 if (
SDValue Impossible = isImpossibleCompare())
18693 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
18697 PPCISD::STORE_COND, dl,
18699 MemNode->getMemoryVT(), MemNode->getMemOperand());
18703 if (
N->getOperand(0) == LHS.getValue(1))
18714 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other, InChain,
18716 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
18722 assert(isDot &&
"Can't compare against a vector result!");
18724 if (
SDValue Impossible = isImpossibleCompare())
18727 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
18734 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
18739 switch (LHS.getConstantOperandVal(1)) {
18755 return DAG.
getNode(PPCISD::COND_BRANCH, dl, MVT::Other,
N->getOperand(0),
18758 N->getOperand(4), CompNode.
getValue(1));
18763 return DAGCombineBuildVector(
N, DCI);
18770 return DAGCombineBitcast(
N, DCI);
18781 EVT VT =
N->getValueType(0);
18782 if (VT == MVT::i64 && !Subtarget.isPPC64())
18784 if ((VT != MVT::i32 && VT != MVT::i64) ||
18792 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
18812 const APInt &DemandedElts,
18814 unsigned Depth)
const {
18816 switch (
Op.getOpcode()) {
18818 case PPCISD::LBRX: {
18821 Known.Zero = 0xFFFF0000;
18824 case PPCISD::ADDE: {
18825 if (
Op.getResNo() == 0) {
18830 Known.Zero = ~1ULL;
18835 switch (
Op.getConstantOperandVal(0)) {
18837 case Intrinsic::ppc_altivec_vcmpbfp_p:
18838 case Intrinsic::ppc_altivec_vcmpeqfp_p:
18839 case Intrinsic::ppc_altivec_vcmpequb_p:
18840 case Intrinsic::ppc_altivec_vcmpequh_p:
18841 case Intrinsic::ppc_altivec_vcmpequw_p:
18842 case Intrinsic::ppc_altivec_vcmpequd_p:
18843 case Intrinsic::ppc_altivec_vcmpequq_p:
18844 case Intrinsic::ppc_altivec_vcmpgefp_p:
18845 case Intrinsic::ppc_altivec_vcmpgtfp_p:
18846 case Intrinsic::ppc_altivec_vcmpgtsb_p:
18847 case Intrinsic::ppc_altivec_vcmpgtsh_p:
18848 case Intrinsic::ppc_altivec_vcmpgtsw_p:
18849 case Intrinsic::ppc_altivec_vcmpgtsd_p:
18850 case Intrinsic::ppc_altivec_vcmpgtsq_p:
18851 case Intrinsic::ppc_altivec_vcmpgtub_p:
18852 case Intrinsic::ppc_altivec_vcmpgtuh_p:
18853 case Intrinsic::ppc_altivec_vcmpgtuw_p:
18854 case Intrinsic::ppc_altivec_vcmpgtud_p:
18855 case Intrinsic::ppc_altivec_vcmpgtuq_p:
18862 switch (
Op.getConstantOperandVal(1)) {
18865 case Intrinsic::ppc_load2r:
18867 Known.Zero = 0xFFFF0000;
18877 switch (Subtarget.getCPUDirective()) {
18899 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
18907 uint64_t LoopSize = 0;
18908 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
18910 LoopSize +=
TII->getInstSizeInBytes(J);
18915 if (LoopSize > 16 && LoopSize <= 32)
18929 if (Constraint.
size() == 1) {
18930 switch (Constraint[0]) {
18948 }
else if (Constraint ==
"wc") {
18950 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
18951 Constraint ==
"wf" || Constraint ==
"ws" ||
18952 Constraint ==
"wi" || Constraint ==
"ww") {
18965 Value *CallOperandVal =
info.CallOperandVal;
18968 if (!CallOperandVal)
18975 else if ((
StringRef(constraint) ==
"wa" ||
18987 switch (*constraint) {
19017std::pair<unsigned, const TargetRegisterClass *>
19021 if (Constraint.
size() == 1) {
19023 switch (Constraint[0]) {
19025 if (VT == MVT::i64 && Subtarget.isPPC64())
19026 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
19027 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
19029 if (VT == MVT::i64 && Subtarget.isPPC64())
19030 return std::make_pair(0U, &PPC::G8RCRegClass);
19031 return std::make_pair(0U, &PPC::GPRCRegClass);
19037 if (Subtarget.hasSPE()) {
19038 if (VT == MVT::f32 || VT == MVT::i32)
19039 return std::make_pair(0U, &PPC::GPRCRegClass);
19040 if (VT == MVT::f64 || VT == MVT::i64)
19041 return std::make_pair(0U, &PPC::SPERCRegClass);
19043 if (VT == MVT::f32 || VT == MVT::i32)
19044 return std::make_pair(0U, &PPC::F4RCRegClass);
19045 if (VT == MVT::f64 || VT == MVT::i64)
19046 return std::make_pair(0U, &PPC::F8RCRegClass);
19050 if (Subtarget.hasAltivec() && VT.
isVector())
19051 return std::make_pair(0U, &PPC::VRRCRegClass);
19052 else if (Subtarget.hasVSX())
19054 return std::make_pair(0U, &PPC::VFRCRegClass);
19057 return std::make_pair(0U, &PPC::CRRCRegClass);
19059 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
19061 return std::make_pair(0U, &PPC::CRBITRCRegClass);
19062 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
19063 Constraint ==
"wf" || Constraint ==
"wi") &&
19064 Subtarget.hasVSX()) {
19068 return std::make_pair(0U, &PPC::VSRCRegClass);
19069 if (VT == MVT::f32 && Subtarget.hasP8Vector())
19070 return std::make_pair(0U, &PPC::VSSRCRegClass);
19071 return std::make_pair(0U, &PPC::VSFRCRegClass);
19072 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
19073 if (VT == MVT::f32 && Subtarget.hasP8Vector())
19074 return std::make_pair(0U, &PPC::VSSRCRegClass);
19076 return std::make_pair(0U, &PPC::VSFRCRegClass);
19077 }
else if (Constraint ==
"lr") {
19078 if (VT == MVT::i64)
19079 return std::make_pair(0U, &PPC::LR8RCRegClass);
19081 return std::make_pair(0U, &PPC::LRRCRegClass);
19086 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
19090 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
19091 int VSNum = atoi(Constraint.
data() + 3);
19092 assert(VSNum >= 0 && VSNum <= 63 &&
19093 "Attempted to access a vsr out of range");
19095 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
19096 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
19101 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
19102 int RegNum = atoi(Constraint.
data() + 2);
19103 if (RegNum > 31 || RegNum < 0)
19105 if (VT == MVT::f32 || VT == MVT::i32)
19106 return Subtarget.hasSPE()
19107 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
19108 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
19109 if (VT == MVT::f64 || VT == MVT::i64)
19110 return Subtarget.hasSPE()
19111 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
19112 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
19116 std::pair<unsigned, const TargetRegisterClass *> R =
19125 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
19126 PPC::GPRCRegClass.contains(R.first))
19127 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
19128 PPC::sub_32, &PPC::G8RCRegClass),
19129 &PPC::G8RCRegClass);
19132 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
19133 R.first = PPC::CR0;
19134 R.second = &PPC::CRRCRegClass;
19137 if (Subtarget.isAIXABI() && !Subtarget.isAIXExtendedAltivecABI()) {
19138 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
19139 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
19140 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
19141 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
19142 "default AIX AltiVec ABI and cannot be used\n";
19152 std::vector<SDValue> &
Ops,
19157 if (Constraint.
size() > 1)
19160 char Letter = Constraint[0];
19175 EVT TCVT = MVT::i64;
19216 if (Result.getNode()) {
19217 Ops.push_back(Result);
19228 if (
I.getNumOperands() <= 1)
19232 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
19233 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
19234 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
19237 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
19253 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
19265 switch (AM.
Scale) {
19293 unsigned Depth =
Op.getConstantOperandVal(0);
19317 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
19325 unsigned Depth =
Op.getConstantOperandVal(0);
19332 bool isPPC64 = PtrVT == MVT::i64;
19338 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
19340 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
19346 FrameAddr, MachinePointerInfo());
19350#define GET_REGISTER_MATCHER
19351#include "PPCGenAsmMatcher.inc"
19355 bool IsPPC64 = Subtarget.isPPC64();
19367 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
19373 Reg = Reg.id() - PPC::R0 + PPC::X0;
19380 if (Subtarget.is32BitELFABI())
19385 if (Subtarget.isAIXABI())
19399 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
19415 case Intrinsic::ppc_atomicrmw_xchg_i128:
19416 case Intrinsic::ppc_atomicrmw_add_i128:
19417 case Intrinsic::ppc_atomicrmw_sub_i128:
19418 case Intrinsic::ppc_atomicrmw_nand_i128:
19419 case Intrinsic::ppc_atomicrmw_and_i128:
19420 case Intrinsic::ppc_atomicrmw_or_i128:
19421 case Intrinsic::ppc_atomicrmw_xor_i128:
19422 case Intrinsic::ppc_cmpxchg_i128:
19424 Info.memVT = MVT::i128;
19425 Info.ptrVal =
I.getArgOperand(0);
19427 Info.align =
Align(16);
19432 case Intrinsic::ppc_atomic_load_i128:
19434 Info.memVT = MVT::i128;
19435 Info.ptrVal =
I.getArgOperand(0);
19437 Info.align =
Align(16);
19441 case Intrinsic::ppc_atomic_store_i128:
19443 Info.memVT = MVT::i128;
19444 Info.ptrVal =
I.getArgOperand(2);
19446 Info.align =
Align(16);
19450 case Intrinsic::ppc_altivec_lvx:
19451 case Intrinsic::ppc_altivec_lvxl:
19452 case Intrinsic::ppc_altivec_lvebx:
19453 case Intrinsic::ppc_altivec_lvehx:
19454 case Intrinsic::ppc_altivec_lvewx:
19455 case Intrinsic::ppc_vsx_lxvd2x:
19456 case Intrinsic::ppc_vsx_lxvw4x:
19457 case Intrinsic::ppc_vsx_lxvd2x_be:
19458 case Intrinsic::ppc_vsx_lxvw4x_be:
19459 case Intrinsic::ppc_vsx_lxvl:
19460 case Intrinsic::ppc_vsx_lxvll: {
19463 case Intrinsic::ppc_altivec_lvebx:
19466 case Intrinsic::ppc_altivec_lvehx:
19469 case Intrinsic::ppc_altivec_lvewx:
19472 case Intrinsic::ppc_vsx_lxvd2x:
19473 case Intrinsic::ppc_vsx_lxvd2x_be:
19483 Info.ptrVal =
I.getArgOperand(0);
19486 Info.align =
Align(1);
19491 case Intrinsic::ppc_altivec_stvx:
19492 case Intrinsic::ppc_altivec_stvxl:
19493 case Intrinsic::ppc_altivec_stvebx:
19494 case Intrinsic::ppc_altivec_stvehx:
19495 case Intrinsic::ppc_altivec_stvewx:
19496 case Intrinsic::ppc_vsx_stxvd2x:
19497 case Intrinsic::ppc_vsx_stxvw4x:
19498 case Intrinsic::ppc_vsx_stxvd2x_be:
19499 case Intrinsic::ppc_vsx_stxvw4x_be:
19500 case Intrinsic::ppc_vsx_stxvl:
19501 case Intrinsic::ppc_vsx_stxvll: {
19504 case Intrinsic::ppc_altivec_stvebx:
19507 case Intrinsic::ppc_altivec_stvehx:
19510 case Intrinsic::ppc_altivec_stvewx:
19513 case Intrinsic::ppc_vsx_stxvd2x:
19514 case Intrinsic::ppc_vsx_stxvd2x_be:
19524 Info.ptrVal =
I.getArgOperand(1);
19527 Info.align =
Align(1);
19532 case Intrinsic::ppc_stdcx:
19533 case Intrinsic::ppc_stwcx:
19534 case Intrinsic::ppc_sthcx:
19535 case Intrinsic::ppc_stbcx: {
19537 auto Alignment =
Align(8);
19539 case Intrinsic::ppc_stdcx:
19542 case Intrinsic::ppc_stwcx:
19544 Alignment =
Align(4);
19546 case Intrinsic::ppc_sthcx:
19548 Alignment =
Align(2);
19550 case Intrinsic::ppc_stbcx:
19552 Alignment =
Align(1);
19557 Info.ptrVal =
I.getArgOperand(0);
19559 Info.align = Alignment;
19577 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
19578 if (
Op.isMemset() && Subtarget.hasVSX()) {
19579 uint64_t TailSize =
Op.size() % 16;
19583 if (TailSize > 2 && TailSize <= 4) {
19588 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
19593 if (Subtarget.isPPC64()) {
19604 assert(Ty->isIntegerTy());
19606 unsigned BitSize = Ty->getPrimitiveSizeInBits();
19607 return !(BitSize == 0 || BitSize > 64);
19615 return NumBits1 == 64 && NumBits2 == 32;
19623 return NumBits1 == 64 && NumBits2 == 32;
19630 EVT MemVT = LD->getMemoryVT();
19631 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
19632 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
19648 "invalid fpext types");
19650 if (DestVT == MVT::f128)
19665 unsigned *
Fast)
const {
19679 !Subtarget.allowsUnalignedFPAccess())
19683 if (Subtarget.hasVSX()) {
19684 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
19685 VT != MVT::v4f32 && VT != MVT::v4i32)
19692 if (VT == MVT::ppcf128)
19707 if (!ConstNode->getAPIntValue().isSignedIntN(64))
19715 int64_t
Imm = ConstNode->getSExtValue();
19720 uint64_t UImm =
static_cast<uint64_t
>(
Imm);
19736 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
19738 switch (Ty->getScalarType()->getTypeID()) {
19743 return Subtarget.hasP9Vector();
19751 if (!
I->hasOneUse())
19755 assert(
User &&
"A single use instruction with no uses.");
19757 switch (
I->getOpcode()) {
19758 case Instruction::FMul: {
19760 if (
User->getOpcode() != Instruction::FSub &&
19761 User->getOpcode() != Instruction::FAdd)
19767 bool AllowContract =
I->getFastMathFlags().allowContract() &&
19768 User->getFastMathFlags().allowContract();
19774 case Instruction::Load: {
19787 if (
User->getOpcode() != Instruction::Store)
19807 static const MCPhysReg ScratchRegs[] = {
19808 PPC::X12, PPC::LR8, PPC::CTR8, 0
19811 return ScratchRegs;
19816 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
19821 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
19826 EVT VT ,
unsigned DefinedValues)
const {
19827 if (VT == MVT::v2i64)
19828 return Subtarget.hasDirectMove();
19830 if (Subtarget.hasVSX())
19857 return PPCISD::FNMSUB;
19858 case PPCISD::FNMSUB:
19864 bool LegalOps,
bool OptForSize,
19866 unsigned Depth)
const {
19870 unsigned Opc =
Op.getOpcode();
19871 EVT VT =
Op.getValueType();
19875 case PPCISD::FNMSUB:
19895 if (Flags.hasNoSignedZeros()) {
19899 N0Cost,
Depth + 1);
19903 N1Cost,
Depth + 1);
19905 if (NegN0 && N0Cost <= N1Cost) {
19906 Cost = std::min(N0Cost, N2Cost);
19908 }
else if (NegN1) {
19909 Cost = std::min(N1Cost, N2Cost);
19929 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
19936 bool ForCodeSize)
const {
19937 if (!VT.
isSimple() || !Subtarget.hasVSX())
19947 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
19952 APSInt IntResult(16,
false);
19957 if (IsExact && IntResult <= 15 && IntResult >= -16)
19974 unsigned Opcode =
N->getOpcode();
19994 if (Mask->getZExtValue() == OpSizeInBits - 1)
20001 DAGCombinerInfo &DCI)
const {
20002 EVT VT =
N->getValueType(0);
20005 unsigned Opc =
N->getOpcode();
20007 "Unexpected opcode.");
20014 if (EltTy != MVT::i64 && EltTy != MVT::i32)
20019 bool AddSplatCase =
false;
20023 AddSplatCase =
true;
20027 if (!AddSplatCase) {
20031 unsigned SplatBitSize;
20033 APInt APSplatBits, APSplatUndef;
20035 bool BVNIsConstantSplat =
20037 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
20038 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
20049 if (SplatBits == (EltBits - 1)) {
20053 NewOpc = PPCISD::SHL;
20056 NewOpc = PPCISD::SRL;
20059 NewOpc = PPCISD::SRA;
20063 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
20071 if (EltTy != MVT::i64 || SplatBits != 1)
20074 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
20077SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20081 if (
N->getValueType(0).isVector())
20082 return combineVectorShift(
N, DCI);
20086 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
20089 N->getValueType(0) != MVT::i64)
20100 SDValue ShiftBy = SDValue(CN1, 0);
20104 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
20110SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20114 if (
N->getValueType(0).isVector())
20115 return combineVectorShift(
N, DCI);
20120SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20124 if (
N->getValueType(0).isVector())
20125 return combineVectorShift(
N, DCI);
20136 if (!Subtarget.isPPC64())
20142 auto isZextOfCompareWithConstant = [](
SDValue Op) {
20144 Op.getValueType() != MVT::i64)
20148 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
20149 Cmp.getOperand(0).getValueType() != MVT::i64)
20153 int64_t NegConstant = 0 -
Constant->getSExtValue();
20162 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
20163 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
20166 if (LHSHasPattern && !RHSHasPattern)
20168 else if (!LHSHasPattern && !RHSHasPattern)
20172 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
20175 SDValue Z = Cmp.getOperand(0);
20177 int64_t NegConstant = 0 -
Constant->getSExtValue();
20190 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20208 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
20238 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20241 if (
LHS.getOpcode() != PPCISD::MAT_PCREL_ADDR)
20249 if (!GSDN || !ConstNode)
20277 EVT VT =
N->getValueType(0);
20278 if (!Subtarget.hasVSX())
20282 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
20294 unsigned NumOfEles =
RHS.getNumOperands();
20295 for (
unsigned i = 0; i < NumOfEles; ++i) {
20297 if (!CN || CN->getSExtValue() != 1)
20312SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20334 DAGCombinerInfo &DCI)
const {
20336 if (Subtarget.useCRBits()) {
20338 if (SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
20339 return CRTruncValue;
20346 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
20349 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
20359 EltToExtract = EltToExtract ? 0 : 1;
20369 return DCI.DAG.getNode(
20371 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
20376SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
20377 SelectionDAG &DAG = DCI.DAG;
20380 if (!ConstOpOrElement)
20388 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
20389 switch (this->Subtarget.getCPUDirective()) {
20412 return IsAddOne && IsNeg ? VT.
isVector() :
true;
20416 EVT VT =
N->getValueType(0);
20421 APInt MulAmtAbs = MulAmt.
abs();
20423 if ((MulAmtAbs - 1).isPowerOf2()) {
20427 if (!IsProfitable(IsNeg,
true, VT))
20440 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
20444 if (!IsProfitable(IsNeg,
false, VT))
20465 DAGCombinerInfo &DCI)
const {
20469 SDNodeFlags
Flags =
N->getFlags();
20470 EVT VT =
N->getValueType(0);
20471 SelectionDAG &DAG = DCI.DAG;
20472 unsigned Opc =
N->getOpcode();
20474 bool LegalOps = !DCI.isBeforeLegalizeOps();
20482 if (!
Flags.hasNoSignedZeros())
20498bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
20500 if (!Subtarget.is64BitELFABI())
20510 if (!TM.Options.GuaranteedTailCallOpt && !
EnableSCO)
20515 if (!Callee ||
Callee->isVarArg())
20528bool PPCTargetLowering::
20529isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
20534 if (CI->getBitWidth() > 64)
20536 int64_t ConstVal = CI->getZExtValue();
20538 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
20547PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
20553 if ((Flags & FlagSet) == FlagSet)
20556 if ((Flags & FlagSet) == FlagSet)
20559 if ((Flags & FlagSet) == FlagSet)
20562 if ((Flags & FlagSet) == FlagSet)
20583 if ((FrameIndexAlign % 4) != 0)
20584 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
20585 if ((FrameIndexAlign % 16) != 0)
20586 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
20590 if ((FrameIndexAlign % 4) == 0)
20592 if ((FrameIndexAlign % 16) == 0)
20606 if ((
Imm & 0x3) == 0)
20608 if ((
Imm & 0xf) == 0)
20614 const APInt &ConstImm = CN->getAPIntValue();
20633 const APInt &ConstImm = CN->getAPIntValue();
20643 }
else if (
RHS.getOpcode() == PPCISD::Lo && !
RHS.getConstantOperandVal(1))
20654 return (
N.getOpcode() == PPCISD::MAT_PCREL_ADDR ||
20663unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
20668 if (!Subtarget.hasP9Vector())
20673 if (Subtarget.hasPrefixInstrs())
20676 if (Subtarget.hasSPE())
20685 unsigned ParentOp = Parent->
getOpcode();
20689 if ((ID == Intrinsic::ppc_vsx_lxvp) || (ID == Intrinsic::ppc_vsx_stxvp)) {
20690 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
20702 if (LSB->isIndexed())
20708 assert(MN &&
"Parent should be a MemSDNode!");
20713 "Not expecting scalar integers larger than 16 bytes!");
20716 else if (
Size == 32)
20723 else if (
Size == 256) {
20724 assert(Subtarget.pairedVectorMemops() &&
20725 "256-bit vectors are only available when paired vector memops is "
20733 else if (MemVT == MVT::f128 || MemVT.
isVector())
20764 FlagSet &= ~PPC::MOF_NoExt;
20769 bool IsNonP1034BitConst =
20773 IsNonP1034BitConst)
20786 int16_t ForceXFormImm = 0;
20789 Disp =
N.getOperand(0);
20790 Base =
N.getOperand(1);
20801 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
20802 Disp =
N.getOperand(0);
20803 Base =
N.getOperand(1);
20808 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20817 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
20823 if (PartVT == MVT::f64 &&
20824 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
20833SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
20837 EVT RetVT =
Op.getValueType();
20844 EVT ArgVT =
N.getValueType();
20848 Entry.IsZExt = !Entry.IsSExt;
20849 Args.push_back(Entry);
20857 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
20870SDValue PPCTargetLowering::lowerLibCallBasedOnType(
20871 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
20873 if (
Op.getValueType() == MVT::f32)
20874 return lowerToLibCall(LibCallFloatName,
Op, DAG);
20876 if (
Op.getValueType() == MVT::f64)
20877 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
20882bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
20883 SDNodeFlags
Flags =
Op.getNode()->getFlags();
20884 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
20888bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
20889 return Op.getNode()->getFlags().hasApproximateFuncs();
20892bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
20897SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
20898 const char *LibCallFloatName,
20899 const char *LibCallDoubleNameFinite,
20900 const char *LibCallFloatNameFinite,
20903 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
20906 if (!isLowringToMASSFiniteSafe(
Op))
20907 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
20910 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
20911 LibCallDoubleNameFinite,
Op, DAG);
20915 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
20916 "__xl_powf_finite",
Op, DAG);
20920 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
20921 "__xl_sinf_finite",
Op, DAG);
20925 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
20926 "__xl_cosf_finite",
Op, DAG);
20930 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
20931 "__xl_logf_finite",
Op, DAG);
20935 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
20936 "__xl_log10f_finite",
Op, DAG);
20940 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
20941 "__xl_expf_finite",
Op, DAG);
20966 unsigned Flags = computeMOFlags(Parent,
N, DAG);
20977 assert(Subtarget.isUsingPCRelativeCalls() &&
20978 "Must be using PC-Relative calls when a valid PC-Relative node is "
21008 Disp =
N.getOperand(1).getOperand(0);
21013 Base =
N.getOperand(0);
21021 EVT CNType = CN->getValueType(0);
21022 uint64_t CNImm = CN->getZExtValue();
21033 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
21035 int32_t Addr = (int32_t)CNImm;
21040 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
21056 unsigned Opcode =
N.getOpcode();
21064 Base =
N.getOperand(0);
21083 Base = FI ?
N :
N.getOperand(1);
21084 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
21095 bool IsVarArg)
const {
21105 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
21142 return Intrinsic::ppc_atomicrmw_xchg_i128;
21144 return Intrinsic::ppc_atomicrmw_add_i128;
21146 return Intrinsic::ppc_atomicrmw_sub_i128;
21148 return Intrinsic::ppc_atomicrmw_and_i128;
21150 return Intrinsic::ppc_atomicrmw_or_i128;
21152 return Intrinsic::ppc_atomicrmw_xor_i128;
21154 return Intrinsic::ppc_atomicrmw_nand_i128;
21162 Module *M = Builder.getModule();
21166 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
21168 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
21169 Value *LoHi = Builder.CreateIntrinsic(
21171 {AlignedAddr, IncrLo, IncrHi});
21172 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21173 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21174 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21175 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21176 return Builder.CreateOr(
21177 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21184 Module *M = Builder.getModule();
21190 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
21192 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
21193 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
21195 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
21198 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
21200 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
21201 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
21202 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
21203 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
21204 return Builder.CreateOr(
21205 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
21209 return Subtarget.useCRBits();
21214bool PPCTargetLowering::isShuffleMaskLegal(
ArrayRef<int> Mask,
EVT VT)
const {
21225 DAGCombinerInfo &DCI)
const {
21230 EVT ResVT =
N->getValueType(0);
21232 EVT SrcVT = Src.getValueType();
21237 if (ResVT != MVT::i16 && ResVT != MVT::i8)
21240 GenerateVBPERM(DAG, dl, Src, SrcVT, TruncResVT, IsLittleEndian);
21253 bool IsV16i8 = (ResVT == MVT::v16i1 && SrcVT == MVT::v16i8);
21254 bool IsV8i16 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i16);
21255 bool IsV8i8 = (ResVT == MVT::v8i1 && SrcVT == MVT::v8i8);
21257 if (!IsV16i8 && !IsV8i16 && !IsV8i8)
21265 SmallVector<int, 16> BitIndices(16, 128);
21269 BitIndices[
Idx] = EltSize * (NumElts -
Idx) - 1;
21270 if (IsV8i8 && IsLE)
21271 BitIndices[
Idx] += 64;
21274 std::reverse(BitIndices.begin(), BitIndices.end());
21276 for (
auto Idx : BitIndices)
21281 DAG.
getConstant(Intrinsic::ppc_altivec_vbpermq, dl, MVT::i32),
21289 bool BVNIsConstantSplat,
21290 unsigned SplatBitSize)
const {
21292 if (!BVNIsConstantSplat || !Subtarget.hasVSX() || !Subtarget.hasP8Vector() ||
21293 Subtarget.hasP10Vector())
21296 EVT VT =
Op->getValueType(0);
21297 if (!((SplatBitSize == 64 && VT == MVT::v2f64) ||
21298 (SplatBitSize == 32 && VT == MVT::v4f32)))
21305 APFloat APFloatVal = CN->getValueAPF();
21307 APSInt IntResult(16,
false);
21310 if (!(IsExact && IntResult <= 15 && IntResult >= -16 && !APFloatVal.
isZero()))
21313 int64_t
IntVal = IntResult.getSExtValue();
21318 if (SplatBitSize == 64)
21321 DAG.
getConstant(Intrinsic::ppc_vsx_xvcvsxwdp, dl, MVT::i32), IntSplat);
21323 return DAG.
getNode(PPCISD::XVCVSXWSP, dl, MVT::v4f32, IntSplat);
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
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 SDValue GeneratePerfectShuffle(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 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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).
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("ppc-expose-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 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 DAGCombineSube(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
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 cl::opt< bool > EnableILPPref("ppc-ilp-pref", cl::desc("Set the node scheduling preference to ILP on PPC"), cl::init(true), cl::Hidden)
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 cl::opt< bool > EnableInnermostLoopAlign32("ppc-innermost-loop-align32", cl::desc("Align innermost loops to 32 bytes on ppc"), cl::init(true), cl::Hidden)
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 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 cl::opt< bool > EnablePerfectShuffle("ppc-perfect-shuffle", cl::desc("enable vector permute decomposition"), cl::init(false), cl::Hidden)
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 bool canConvertToVcmpequb(SDValue &LHS, SDValue &RHS, bool IsPPC64)
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 CallInst * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
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...
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 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 std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
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 void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static cl::opt< bool > EnableP10StoreForward("ppc-p10-store-forward", cl::desc("enable P10 store forward-friendly conversion"), cl::init(true), cl::Hidden)
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)
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())
cl::opt< bool > EnableAutoPairedVecSt("ppc-auto-paired-vec-st", cl::desc("enable automatically generated 32byte paired vector stores"), cl::init(false), cl::Hidden)
static cl::opt< bool > EnableSCO("ppc-sco", cl::desc("enable sibling call optimization on ppc"), cl::init(true), cl::Hidden)
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.
cl::opt< bool > EnablePPCGenScalarMASSEntries
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 bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static cl::opt< bool > EnablePPCPreinc("ppc-preinc", cl::desc("enable preincrement load/store generation on PPC"), cl::init(true), cl::Hidden)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
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 cl::opt< bool > EnablePPCUnaligned("ppc-unaligned", cl::desc("enable unaligned load/store generation on PPC"), cl::init(true), cl::Hidden)
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
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
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 constexpr int TPOffset
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
opStatus convertToInteger(MutableArrayRef< integerPart > Input, unsigned int Width, bool IsSigned, roundingMode RM, bool *IsExact) 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 ult(const APInt &RHS) const
Unsigned less than comparison.
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 constexpr BranchProbability getOne()
static constexpr 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 or function.
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.
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...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
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.
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
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.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
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.
Register getExceptionSelectorRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
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.
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.
bool fenceClearsLoadLinkedReservation() const override
True unless the subtarget has FeatureFenceKeepsReservation.
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
Register getExceptionPointerRegister(ExceptionHandling EH, const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
Align getPrefLoopAlignment(MachineLoop *ML, const MachineBasicBlock *BlockToAlign) const override
Return the preferred loop alignment.
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...
FPImmAction getFPImmAction(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns how the legalizer should materialize the specified FP immediate.
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
bool isJumpTableRelative() const override
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
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(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
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, in exactly one operand.
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...
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 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...
bool willNotOverflowSub(bool IsSigned, SDValue N0, SDValue N1) const
Determine if the result of the sub of 2 nodes can never overflow.
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).
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
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 getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
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 SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Helper function to build ISD::STORE nodes.
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 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 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 MMOMetadata &Metadata=MMOMetadata())
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 ...
LLVM_ABI bool SignBitIsZero(SDValue Op, unsigned Depth=0) const
Return true if the sign bit of Op is known to be zero.
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 getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const MMOMetadata &Metadata=MMOMetadata())
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI bool isKnownNeverZero(SDValue Op, unsigned Depth=0) const
Test whether the given SDValue is known to contain non-zero value(s).
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.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr, const MachineBasicBlock *BlockToAlign=nullptr) const
Return the preferred loop alignment.
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.
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 setPartialReduceMLAAction(unsigned Opc, MVT AccVT, MVT InputVT, LegalizeAction Action)
Indicate how a PARTIAL_REDUCE_U/SMLA node with Acc type AccVT and Input type InputVT should be treate...
FPImmAction
How the legalizer should materialize a floating-point immediate.
@ ConstantPool
Load the immediate from the constant pool.
@ Legal
The target can instruction select the immediate natively.
@ Bitcast
Build the immediate as a bitcast of an integer constant with the same bits.
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.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
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 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)
bool isSized() const
Return true if it makes sense to take the size of this type.
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 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.
@ PARTIAL_REDUCE_SMLA
PARTIAL_REDUCE_[U|S]MLA(Accumulator, Input1, Input2) The partial reduction nodes sign or zero extend ...
@ 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 - Same as FMINNUM/FMAXNUM, except that a signaling NaN operand deterministi...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ CopyToReg
CopyToReg - This node has three operands: a chain, a register number to set to this value,...
@ 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 - Same semantics as the llvm.minnum/maxnum intrinsics.
@ 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...
@ SCMP
[US]CMP - 3-way comparison of signed or unsigned integers.
@ 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.
@ 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
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
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.
RelativeUniformCounterPtr Values
@ Known
Known to have no common set bits.
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,...
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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 bool isOneOrOneSplat(SDValue V, bool AllowUndefs=false)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
const unsigned PerfectShuffleTable[6561+1]
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...
@ Fast
Assign the register banks as fast as possible (default).
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
LLVM_ABI 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.
@ End
Run the machine verifier once, at the end of the pipeline.
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.
MCRegisterClass TargetRegisterClass
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 bitsLT(EVT VT) const
Return true if this has less 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.
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.
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.