71#include "llvm/IR/IntrinsicsPowerPC.h"
106#define DEBUG_TYPE "ppc-lowering"
128 cl::desc(
"disable vector permute decomposition"),
132 "disable-auto-paired-vec-st",
133 cl::desc(
"disable automatically generated 32byte paired vector stores"),
138 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
142 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
146 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
147 "function to use initial-exec"));
152 "Number of shuffles lowered to a VPERM or XXPERM");
153STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
176 initializeAddrModeMap();
179 bool isPPC64 = Subtarget.
isPPC64();
188 if (!Subtarget.hasEFPU2())
213 if (Subtarget.isISA3_0()) {
243 if (!Subtarget.hasSPE()) {
251 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
252 for (
MVT VT : ScalarIntVTs) {
259 if (Subtarget.useCRBits()) {
262 if (isPPC64 || Subtarget.hasFPCVT()) {
265 isPPC64 ? MVT::i64 : MVT::i32);
268 isPPC64 ? MVT::i64 : MVT::i32);
272 isPPC64 ? MVT::i64 : MVT::i32);
275 isPPC64 ? MVT::i64 : MVT::i32);
279 isPPC64 ? MVT::i64 : MVT::i32);
282 isPPC64 ? MVT::i64 : MVT::i32);
286 isPPC64 ? MVT::i64 : MVT::i32);
289 isPPC64 ? MVT::i64 : MVT::i32);
336 if (Subtarget.isISA3_0()) {
371 if (!Subtarget.hasSPE()) {
376 if (Subtarget.hasVSX()) {
381 if (Subtarget.hasFSQRT()) {
386 if (Subtarget.hasFPRND()) {
427 if (Subtarget.hasSPE()) {
435 if (Subtarget.hasSPE())
441 if (!Subtarget.hasFSQRT() &&
442 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
446 if (!Subtarget.hasFSQRT() &&
447 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
448 Subtarget.hasFRES()))
451 if (Subtarget.hasFCPSGN()) {
459 if (Subtarget.hasFPRND()) {
473 if (Subtarget.isISA3_1()) {
484 if (Subtarget.isISA3_0()) {
504 if (!Subtarget.useCRBits()) {
517 if (!Subtarget.useCRBits())
520 if (Subtarget.hasFPU()) {
531 if (!Subtarget.useCRBits())
536 if (Subtarget.hasSPE()) {
560 if (Subtarget.hasDirectMove() && isPPC64) {
565 if (
TM.Options.UnsafeFPMath) {
668 if (Subtarget.hasSPE()) {
690 if (Subtarget.has64BitSupport()) {
705 if (Subtarget.hasLFIWAX() || Subtarget.
isPPC64()) {
711 if (Subtarget.hasSPE()) {
721 if (Subtarget.hasFPCVT()) {
722 if (Subtarget.has64BitSupport()) {
743 if (Subtarget.use64BitRegs()) {
761 if (Subtarget.has64BitSupport()) {
768 if (Subtarget.hasVSX()) {
775 if (Subtarget.hasAltivec()) {
776 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
791 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
804 if (Subtarget.hasVSX()) {
810 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
820 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
894 if (!Subtarget.hasP8Vector()) {
936 if (Subtarget.hasAltivec())
937 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
940 if (Subtarget.hasP8Altivec())
951 if (Subtarget.hasVSX()) {
957 if (Subtarget.hasP8Altivec())
962 if (Subtarget.isISA3_1()) {
1000 if (Subtarget.hasVSX()) {
1003 if (Subtarget.hasP8Vector()) {
1007 if (Subtarget.hasDirectMove() && isPPC64) {
1021 if (
TM.Options.UnsafeFPMath) {
1058 if (Subtarget.hasP8Vector())
1067 if (Subtarget.hasP8Altivec()) {
1094 if (Subtarget.isISA3_1())
1197 if (Subtarget.hasP8Altivec()) {
1202 if (Subtarget.hasP9Vector()) {
1207 if (Subtarget.useCRBits()) {
1266 }
else if (Subtarget.hasVSX()) {
1291 for (
MVT VT : {MVT::f32, MVT::f64}) {
1310 if (Subtarget.hasP9Altivec()) {
1311 if (Subtarget.isISA3_1()) {
1334 if (Subtarget.hasP10Vector()) {
1339 if (Subtarget.pairedVectorMemops()) {
1344 if (Subtarget.hasMMA()) {
1345 if (Subtarget.isISAFuture())
1354 if (Subtarget.has64BitSupport())
1357 if (Subtarget.isISA3_1())
1375 if (Subtarget.hasAltivec()) {
1392 if (Subtarget.hasFPCVT())
1395 if (Subtarget.useCRBits())
1404 if (Subtarget.useCRBits()) {
1435 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1436 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1437 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1438 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1443 if (Subtarget.useCRBits()) {
1549void PPCTargetLowering::initializeAddrModeMap() {
1600 if (MaxAlign == MaxMaxAlign)
1602 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1603 if (MaxMaxAlign >= 32 &&
1604 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1605 MaxAlign =
Align(32);
1606 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1608 MaxAlign =
Align(16);
1609 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1612 if (EltAlign > MaxAlign)
1613 MaxAlign = EltAlign;
1614 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1615 for (
auto *EltTy : STy->elements()) {
1618 if (EltAlign > MaxAlign)
1619 MaxAlign = EltAlign;
1620 if (MaxAlign == MaxMaxAlign)
1633 if (Subtarget.hasAltivec())
1635 return Alignment.
value();
1643 return Subtarget.hasSPE();
1651 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &
Index)
const {
1652 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1655 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1656 if (VTy->getScalarType()->isIntegerTy()) {
1658 if (ElemSizeInBits == 32) {
1662 if (ElemSizeInBits == 64) {
1688 return "PPCISD::FTSQRT";
1690 return "PPCISD::FSQRT";
1695 return "PPCISD::XXSPLTI_SP_TO_DP";
1697 return "PPCISD::XXSPLTI32DX";
1701 return "PPCISD::XXPERM";
1721 return "PPCISD::CALL_RM";
1723 return "PPCISD::CALL_NOP_RM";
1725 return "PPCISD::CALL_NOTOC_RM";
1730 return "PPCISD::BCTRL_RM";
1732 return "PPCISD::BCTRL_LOAD_TOC_RM";
1744 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1746 return "PPCISD::ANDI_rec_1_EQ_BIT";
1748 return "PPCISD::ANDI_rec_1_GT_BIT";
1763 return "PPCISD::ST_VSR_SCAL_INT";
1792 return "PPCISD::PADDI_DTPREL";
1808 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1810 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1820 return "PPCISD::STRICT_FADDRTZ";
1822 return "PPCISD::STRICT_FCTIDZ";
1824 return "PPCISD::STRICT_FCTIWZ";
1826 return "PPCISD::STRICT_FCTIDUZ";
1828 return "PPCISD::STRICT_FCTIWUZ";
1830 return "PPCISD::STRICT_FCFID";
1832 return "PPCISD::STRICT_FCFIDU";
1834 return "PPCISD::STRICT_FCFIDS";
1836 return "PPCISD::STRICT_FCFIDUS";
1839 return "PPCISD::STORE_COND";
1847 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1864 return CFP->getValueAPF().isZero();
1868 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1869 return CFP->getValueAPF().isZero();
1877 return Op < 0 ||
Op == Val;
1889 if (ShuffleKind == 0) {
1892 for (
unsigned i = 0; i != 16; ++i)
1895 }
else if (ShuffleKind == 2) {
1898 for (
unsigned i = 0; i != 16; ++i)
1901 }
else if (ShuffleKind == 1) {
1902 unsigned j = IsLE ? 0 : 1;
1903 for (
unsigned i = 0; i != 8; ++i)
1920 if (ShuffleKind == 0) {
1923 for (
unsigned i = 0; i != 16; i += 2)
1927 }
else if (ShuffleKind == 2) {
1930 for (
unsigned i = 0; i != 16; i += 2)
1934 }
else if (ShuffleKind == 1) {
1935 unsigned j = IsLE ? 0 : 2;
1936 for (
unsigned i = 0; i != 8; i += 2)
1957 if (!Subtarget.hasP8Vector())
1961 if (ShuffleKind == 0) {
1964 for (
unsigned i = 0; i != 16; i += 4)
1970 }
else if (ShuffleKind == 2) {
1973 for (
unsigned i = 0; i != 16; i += 4)
1979 }
else if (ShuffleKind == 1) {
1980 unsigned j = IsLE ? 0 : 4;
1981 for (
unsigned i = 0; i != 8; i += 4)
1998 unsigned LHSStart,
unsigned RHSStart) {
1999 if (
N->getValueType(0) != MVT::v16i8)
2001 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2002 "Unsupported merge size!");
2004 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2005 for (
unsigned j = 0; j != UnitSize; ++j) {
2007 LHSStart+j+i*UnitSize) ||
2009 RHSStart+j+i*UnitSize))
2024 if (ShuffleKind == 1)
2026 else if (ShuffleKind == 2)
2031 if (ShuffleKind == 1)
2033 else if (ShuffleKind == 0)
2049 if (ShuffleKind == 1)
2051 else if (ShuffleKind == 2)
2056 if (ShuffleKind == 1)
2058 else if (ShuffleKind == 0)
2108 unsigned RHSStartValue) {
2109 if (
N->getValueType(0) != MVT::v16i8)
2112 for (
unsigned i = 0; i < 2; ++i)
2113 for (
unsigned j = 0; j < 4; ++j)
2115 i*RHSStartValue+j+IndexOffset) ||
2117 i*RHSStartValue+j+IndexOffset+8))
2139 unsigned indexOffset = CheckEven ? 4 : 0;
2140 if (ShuffleKind == 1)
2142 else if (ShuffleKind == 2)
2148 unsigned indexOffset = CheckEven ? 0 : 4;
2149 if (ShuffleKind == 1)
2151 else if (ShuffleKind == 0)
2167 if (
N->getValueType(0) != MVT::v16i8)
2174 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2177 if (i == 16)
return -1;
2182 if (ShiftAmt < i)
return -1;
2187 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2189 for (++i; i != 16; ++i)
2192 }
else if (ShuffleKind == 1) {
2194 for (++i; i != 16; ++i)
2201 ShiftAmt = 16 - ShiftAmt;
2210 EVT VT =
N->getValueType(0);
2211 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2212 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2215 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2219 if (
N->getMaskElt(0) % EltSize != 0)
2224 unsigned ElementBase =
N->getMaskElt(0);
2227 if (ElementBase >= 16)
2232 for (
unsigned i = 1; i != EltSize; ++i)
2233 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2236 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2237 if (
N->getMaskElt(i) < 0)
continue;
2238 for (
unsigned j = 0; j != EltSize; ++j)
2239 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2256 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2257 "Unexpected element width.");
2258 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2260 unsigned NumOfElem = 16 / Width;
2261 unsigned MaskVal[16];
2262 for (
unsigned i = 0; i < NumOfElem; ++i) {
2263 MaskVal[0] =
N->getMaskElt(i * Width);
2264 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2266 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2270 for (
unsigned int j = 1; j < Width; ++j) {
2271 MaskVal[j] =
N->getMaskElt(i * Width + j);
2272 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2282 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2287 unsigned M0 =
N->getMaskElt(0) / 4;
2288 unsigned M1 =
N->getMaskElt(4) / 4;
2289 unsigned M2 =
N->getMaskElt(8) / 4;
2290 unsigned M3 =
N->getMaskElt(12) / 4;
2291 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2292 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2297 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2298 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2299 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2300 InsertAtByte = IsLE ? 12 : 0;
2305 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2306 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2307 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2308 InsertAtByte = IsLE ? 8 : 4;
2313 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2314 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2315 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2316 InsertAtByte = IsLE ? 4 : 8;
2321 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2322 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2323 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2324 InsertAtByte = IsLE ? 0 : 12;
2331 if (
N->getOperand(1).isUndef()) {
2334 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2335 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2336 InsertAtByte = IsLE ? 12 : 0;
2339 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2340 InsertAtByte = IsLE ? 8 : 4;
2343 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2344 InsertAtByte = IsLE ? 4 : 8;
2347 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2348 InsertAtByte = IsLE ? 0 : 12;
2357 bool &Swap,
bool IsLE) {
2358 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2364 unsigned M0 =
N->getMaskElt(0) / 4;
2365 unsigned M1 =
N->getMaskElt(4) / 4;
2366 unsigned M2 =
N->getMaskElt(8) / 4;
2367 unsigned M3 =
N->getMaskElt(12) / 4;
2371 if (
N->getOperand(1).isUndef()) {
2372 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2373 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2376 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2382 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2386 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2391 ShiftElts = (8 -
M0) % 8;
2392 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2397 ShiftElts = (4 -
M0) % 4;
2402 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2407 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2419 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2424 for (
int i = 0; i < 16; i += Width)
2425 if (
N->getMaskElt(i) != i + Width - 1)
2456 bool &Swap,
bool IsLE) {
2457 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2463 unsigned M0 =
N->getMaskElt(0) / 8;
2464 unsigned M1 =
N->getMaskElt(8) / 8;
2465 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2469 if (
N->getOperand(1).isUndef()) {
2470 if ((
M0 |
M1) < 2) {
2471 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2479 if (
M0 > 1 &&
M1 < 2) {
2481 }
else if (M0 < 2 && M1 > 1) {
2489 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2492 if (M0 < 2 && M1 > 1) {
2494 }
else if (
M0 > 1 &&
M1 < 2) {
2502 DM = (
M0 << 1) + (
M1 & 1);
2517 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2522 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2538 unsigned EltSize = 16/
N->getNumOperands();
2539 if (EltSize < ByteSize) {
2540 unsigned Multiple = ByteSize/EltSize;
2542 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2545 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2546 if (
N->getOperand(i).isUndef())
continue;
2548 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2550 if (!UniquedVals[i&(Multiple-1)].
getNode())
2551 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2552 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2562 bool LeadingZero =
true;
2563 bool LeadingOnes =
true;
2564 for (
unsigned i = 0; i != Multiple-1; ++i) {
2565 if (!UniquedVals[i].
getNode())
continue;
2572 if (!UniquedVals[Multiple-1].
getNode())
2579 if (!UniquedVals[Multiple-1].
getNode())
2581 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2590 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2591 if (
N->getOperand(i).isUndef())
continue;
2593 OpVal =
N->getOperand(i);
2594 else if (OpVal !=
N->getOperand(i))
2600 unsigned ValSizeInBytes = EltSize;
2603 Value = CN->getZExtValue();
2605 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2606 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2612 if (ValSizeInBytes < ByteSize)
return SDValue();
2623 if (MaskVal == 0)
return SDValue();
2626 if (SignExtend32<5>(MaskVal) == MaskVal)
2640 if (!isa<ConstantSDNode>(
N))
2643 Imm = (int16_t)
N->getAsZExtVal();
2644 if (
N->getValueType(0) == MVT::i32)
2645 return Imm == (int32_t)
N->getAsZExtVal();
2647 return Imm == (int64_t)
N->getAsZExtVal();
2665 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2674 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2675 if (Memop->getMemoryVT() == MVT::f64) {
2676 Base =
N.getOperand(0);
2689 if (!isa<ConstantSDNode>(
N))
2692 Imm = (int64_t)
N->getAsZExtVal();
2693 return isInt<34>(Imm);
2720 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2725 Base =
N.getOperand(0);
2728 }
else if (
N.getOpcode() ==
ISD::OR) {
2730 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2742 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2743 Base =
N.getOperand(0);
2814 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2820 Base =
N.getOperand(0);
2823 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2825 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2826 "Cannot handle constant offsets yet!");
2827 Disp =
N.getOperand(1).getOperand(0);
2832 Base =
N.getOperand(0);
2835 }
else if (
N.getOpcode() ==
ISD::OR) {
2838 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2848 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2852 Base =
N.getOperand(0);
2865 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2868 CN->getValueType(0));
2873 if ((CN->getValueType(0) == MVT::i32 ||
2874 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2875 (!EncodingAlignment ||
2876 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2877 int Addr = (int)CN->getZExtValue();
2884 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2905 if (
N.getValueType() != MVT::i64)
2918 Base =
N.getOperand(0);
2934 Base =
N.getOperand(0);
2967 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2968 Base =
N.getOperand(0);
2981 Ty *PCRelCand = dyn_cast<Ty>(
N);
2993 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
2994 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
2995 isValidPCRelNode<JumpTableSDNode>(
N) ||
2996 isValidPCRelNode<BlockAddressSDNode>(
N))
3012 EVT MemVT = LD->getMemoryVT();
3019 if (!ST.hasP8Vector())
3024 if (!ST.hasP9Vector())
3037 if (UI.getUse().get().getResNo() == 0 &&
3059 Ptr = LD->getBasePtr();
3060 VT = LD->getMemoryVT();
3061 Alignment = LD->getAlign();
3062 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3063 Ptr = ST->getBasePtr();
3064 VT = ST->getMemoryVT();
3065 Alignment = ST->getAlign();
3088 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3091 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3104 if (VT != MVT::i64) {
3109 if (Alignment <
Align(4))
3119 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3121 isa<ConstantSDNode>(
Offset))
3136 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3178 const bool Is64Bit = Subtarget.
isPPC64();
3179 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3193 EVT PtrVT =
Op.getValueType();
3209 return getTOCEntry(DAG,
SDLoc(CP), GA);
3212 unsigned MOHiFlag, MOLoFlag;
3219 return getTOCEntry(DAG,
SDLoc(CP), GA);
3279 EVT PtrVT =
Op.getValueType();
3297 return getTOCEntry(DAG,
SDLoc(JT), GA);
3300 unsigned MOHiFlag, MOLoFlag;
3307 return getTOCEntry(DAG,
SDLoc(GA), GA);
3317 EVT PtrVT =
Op.getValueType();
3336 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3345 unsigned MOHiFlag, MOLoFlag;
3356 return LowerGlobalTLSAddressAIX(
Op, DAG);
3358 return LowerGlobalTLSAddressLinux(
Op, DAG);
3382 if (
II->getOpcode() == Instruction::Call)
3383 if (
const CallInst *CI = dyn_cast<const CallInst>(&*
II))
3384 if (
Function *CF = CI->getCalledFunction())
3385 if (CF->isDeclaration() &&
3386 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3388 dyn_cast<GlobalValue>(
II->getOperand(0))) {
3394 unsigned TLSGVCnt = TLSGV.
size();
3404 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3419 bool Is64Bit = Subtarget.
isPPC64();
3423 if (Subtarget.hasAIXShLibTLSModelOpt())
3429 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3430 bool HasAIXSmallTLSGlobalAttr =
false;
3433 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3437 if (GVar->hasAttribute(
"aix-small-tls"))
3438 HasAIXSmallTLSGlobalAttr =
true;
3457 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3458 IsTLSLocalExecModel) {
3478 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3480 "currently only supported on AIX (64-bit mode).");
3486 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3490 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3492 "currently only supported on AIX (64-bit mode).");
3500 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3504 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3507 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3510 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3521 if (HasAIXSmallLocalDynamicTLS) {
3530 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3543 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3544 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3562 bool is64bit = Subtarget.
isPPC64();
3609 if (!
TM.isPositionIndependent())
3668 PtrVT, GOTPtr, TGA, TGA);
3670 PtrVT, TLSAddr, TGA);
3679 EVT PtrVT =
Op.getValueType();
3704 return getTOCEntry(DAG,
DL, GA);
3707 unsigned MOHiFlag, MOLoFlag;
3715 return getTOCEntry(DAG,
DL, GA);
3727 bool IsStrict =
Op->isStrictFPOpcode();
3729 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3733 EVT LHSVT =
LHS.getValueType();
3737 if (LHSVT == MVT::f128) {
3738 assert(!Subtarget.hasP9Vector() &&
3739 "SETCC for f128 is already legal under Power9!");
3750 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3752 if (
Op.getValueType() == MVT::v2i64) {
3755 if (
LHS.getValueType() == MVT::v2i64) {
3763 int ShuffV[] = {1, 0, 3, 2};
3768 dl, MVT::v4i32, Shuff, SetCC32));
3785 if (
C->isAllOnes() ||
C->isZero())
3795 EVT VT =
Op.getValueType();
3804 EVT VT =
Node->getValueType(0);
3808 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3818 if (VT == MVT::i64) {
3849 InChain = OverflowArea.
getValue(1);
3895 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3902 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3908 false,
true,
nullptr, std::nullopt,
3917 return Op.getOperand(0);
3926 "Expecting Inline ASM node.");
3936 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3942 unsigned NumVals =
Flags.getNumOperandRegisters();
3945 switch (
Flags.getKind()) {
3956 for (; NumVals; --NumVals, ++i) {
3957 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3958 if (Reg != PPC::LR && Reg != PPC::LR8)
3983 bool isPPC64 = (PtrVT == MVT::i64);
3989 Entry.Ty = IntPtrTy;
3990 Entry.Node = Trmp;
Args.push_back(Entry);
3994 isPPC64 ? MVT::i64 : MVT::i32);
3995 Args.push_back(Entry);
3997 Entry.Node = FPtr;
Args.push_back(Entry);
3998 Entry.Node = Nest;
Args.push_back(Entry);
4002 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4006 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4007 return CallResult.second;
4021 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4022 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4057 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4066 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4081 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4084 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4086 nextOffset += FrameOffset;
4087 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4090 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4096static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4097 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4098 PPC::F11, PPC::F12, PPC::F13};
4103 unsigned PtrByteSize) {
4105 if (Flags.isByVal())
4106 ArgSize = Flags.getByValSize();
4110 if (!Flags.isInConsecutiveRegs())
4111 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4120 unsigned PtrByteSize) {
4121 Align Alignment(PtrByteSize);
4124 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4125 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4126 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4127 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4128 Alignment =
Align(16);
4131 if (Flags.isByVal()) {
4132 auto BVAlign = Flags.getNonZeroByValAlign();
4133 if (BVAlign > PtrByteSize) {
4134 if (BVAlign.value() % PtrByteSize != 0)
4136 "ByVal alignment is not a multiple of the pointer size");
4138 Alignment = BVAlign;
4143 if (Flags.isInConsecutiveRegs()) {
4147 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4161 unsigned PtrByteSize,
unsigned LinkageSize,
4162 unsigned ParamAreaSize,
unsigned &ArgOffset,
4163 unsigned &AvailableFPRs,
4164 unsigned &AvailableVRs) {
4165 bool UseMemory =
false;
4170 ArgOffset =
alignTo(ArgOffset, Alignment);
4173 if (ArgOffset >= LinkageSize + ParamAreaSize)
4178 if (Flags.isInConsecutiveRegsLast())
4179 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4182 if (ArgOffset > LinkageSize + ParamAreaSize)
4187 if (!Flags.isByVal()) {
4188 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4189 if (AvailableFPRs > 0) {
4193 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4194 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4195 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4196 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4197 if (AvailableVRs > 0) {
4209 unsigned NumBytes) {
4213SDValue PPCTargetLowering::LowerFormalArguments(
4218 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4221 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4224 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4228SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4270 const Align PtrAlign(4);
4279 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4281 CCInfo.PreAnalyzeFormalArguments(Ins);
4284 CCInfo.clearWasPPCF128();
4286 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4299 RC = &PPC::GPRCRegClass;
4302 if (Subtarget.hasP8Vector())
4303 RC = &PPC::VSSRCRegClass;
4304 else if (Subtarget.hasSPE())
4305 RC = &PPC::GPRCRegClass;
4307 RC = &PPC::F4RCRegClass;
4310 if (Subtarget.hasVSX())
4311 RC = &PPC::VSFRCRegClass;
4312 else if (Subtarget.hasSPE())
4314 RC = &PPC::GPRCRegClass;
4316 RC = &PPC::F8RCRegClass;
4321 RC = &PPC::VRRCRegClass;
4324 RC = &PPC::VRRCRegClass;
4328 RC = &PPC::VRRCRegClass;
4335 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4336 assert(i + 1 < e &&
"No second half of double precision argument");
4348 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4349 if (ValVT == MVT::i1)
4364 ArgOffset += ArgSize - ObjSize;
4382 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4387 unsigned MinReservedArea = CCByValInfo.getStackSize();
4388 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4404 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4405 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4407 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4410 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4413 unsigned NumFPArgRegs = std::size(FPArgRegs);
4422 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4426 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4435 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4439 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4454 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4458 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4471 if (!MemOps.
empty())
4482 const SDLoc &dl)
const {
4486 else if (
Flags.isZExt())
4493SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4506 "fastcc not supported on varargs functions");
4512 unsigned PtrByteSize = 8;
4516 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4517 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4520 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4521 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4524 const unsigned Num_GPR_Regs = std::size(GPR);
4526 const unsigned Num_VR_Regs = std::size(VR);
4534 bool HasParameterArea = !isELFv2ABI || isVarArg;
4535 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4536 unsigned NumBytes = LinkageSize;
4537 unsigned AvailableFPRs = Num_FPR_Regs;
4538 unsigned AvailableVRs = Num_VR_Regs;
4539 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4540 if (Ins[i].
Flags.isNest())
4544 PtrByteSize, LinkageSize, ParamAreaSize,
4545 NumBytes, AvailableFPRs, AvailableVRs))
4546 HasParameterArea =
true;
4553 unsigned ArgOffset = LinkageSize;
4554 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4557 unsigned CurArgIdx = 0;
4558 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4560 bool needsLoad =
false;
4561 EVT ObjectVT =
Ins[ArgNo].VT;
4562 EVT OrigVT =
Ins[ArgNo].ArgVT;
4564 unsigned ArgSize = ObjSize;
4566 if (Ins[ArgNo].isOrigArg()) {
4567 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4568 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4573 unsigned CurArgOffset;
4575 auto ComputeArgOffset = [&]() {
4579 ArgOffset =
alignTo(ArgOffset, Alignment);
4580 CurArgOffset = ArgOffset;
4587 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4588 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4593 if (
Flags.isByVal()) {
4594 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4600 ObjSize =
Flags.getByValSize();
4601 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4623 if (HasParameterArea ||
4624 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4631 if (ObjSize < PtrByteSize) {
4635 if (!isLittleEndian) {
4641 if (GPR_idx != Num_GPR_Regs) {
4653 ArgOffset += PtrByteSize;
4662 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4663 if (GPR_idx == Num_GPR_Regs)
4674 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4682 ArgOffset += ArgSize;
4691 if (
Flags.isNest()) {
4696 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4697 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4705 if (GPR_idx != Num_GPR_Regs) {
4710 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4713 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4719 ArgSize = PtrByteSize;
4730 if (FPR_idx != Num_FPR_Regs) {
4733 if (ObjectVT == MVT::f32)
4735 Subtarget.hasP8Vector()
4736 ? &PPC::VSSRCRegClass
4737 : &PPC::F4RCRegClass);
4740 ? &PPC::VSFRCRegClass
4741 : &PPC::F8RCRegClass);
4756 if (ObjectVT == MVT::f32) {
4757 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4775 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4776 ArgOffset += ArgSize;
4777 if (
Flags.isInConsecutiveRegsLast())
4778 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4792 if (VR_idx != Num_VR_Regs) {
4809 if (ObjSize < ArgSize && !isLittleEndian)
4810 CurArgOffset += ArgSize - ObjSize;
4820 unsigned MinReservedArea;
4821 if (HasParameterArea)
4822 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4824 MinReservedArea = LinkageSize;
4841 int Depth = ArgOffset;
4850 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4851 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4863 if (!MemOps.
empty())
4872 unsigned ParamSize) {
4874 if (!isTailCall)
return 0;
4878 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4880 if (SPDiff < FI->getTailCallSPDelta())
4896 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4909 if (!
TM.shouldAssumeDSOLocal(CalleeGV))
4915 const Function *
F = dyn_cast<Function>(CalleeGV);
4916 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4921 F = dyn_cast<Function>(GlobalObj);
4954 if (
TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4955 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4957 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4958 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4970 const unsigned PtrByteSize = 8;
4974 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4975 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4978 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4979 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4982 const unsigned NumGPRs = std::size(GPR);
4983 const unsigned NumFPRs = 13;
4984 const unsigned NumVRs = std::size(VR);
4985 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4987 unsigned NumBytes = LinkageSize;
4988 unsigned AvailableFPRs = NumFPRs;
4989 unsigned AvailableVRs = NumVRs;
4992 if (Param.Flags.isNest())
continue;
4995 LinkageSize, ParamAreaSize, NumBytes,
4996 AvailableFPRs, AvailableVRs))
5007 auto CalleeArgEnd = CB.
arg_end();
5010 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5011 const Value* CalleeArg = *CalleeArgIter;
5012 const Value* CallerArg = &(*CallerArgIter);
5013 if (CalleeArg == CallerArg)
5021 isa<UndefValue>(CalleeArg))
5039 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5049bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5054 bool isCalleeExternalSymbol)
const {
5057 if (
DisableSCO && !TailCallOpt)
return false;
5060 if (isVarArg)
return false;
5136bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5170 if (!
C)
return nullptr;
5172 int Addr =
C->getZExtValue();
5173 if ((
Addr & 3) != 0 ||
5179 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5186struct TailCallArgumentInfo {
5191 TailCallArgumentInfo() =
default;
5201 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5202 SDValue Arg = TailCallArgs[i].Arg;
5203 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5204 int FI = TailCallArgs[i].FrameIdx;
5207 Chain, dl, Arg, FIN,
5216 int SPDiff,
const SDLoc &dl) {
5222 bool isPPC64 = Subtarget.
isPPC64();
5223 int SlotSize = isPPC64 ? 8 : 4;
5224 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5226 NewRetAddrLoc,
true);
5227 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5229 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5239 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5241 int Offset = ArgOffset + SPDiff;
5244 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5246 TailCallArgumentInfo
Info;
5248 Info.FrameIdxOp = FIN;
5256SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5261 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5262 LROpOut = getReturnAddrFrameIndex(DAG);
5280 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5288 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5311 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5321 if (!MemOpChains2.
empty())
5345SDValue PPCTargetLowering::LowerCallResult(
5353 CCRetInfo.AnalyzeCallResult(
5359 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5365 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5368 Chain =
Lo.getValue(1);
5369 InGlue =
Lo.getValue(2);
5373 Chain =
Hi.getValue(1);
5374 InGlue =
Hi.getValue(2);
5411 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5443 bool IsStrictFPCall =
false) {
5447 unsigned RetOpc = 0;
5472 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5478 if (IsStrictFPCall) {
5509 auto isLocalCallee = [&]() {
5514 !isa_and_nonnull<GlobalIFunc>(GV);
5525 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5535 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5538 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5541 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5542 return getAIXFuncEntryPointSymbolSDNode(GV);
5549 const char *SymName = S->getSymbol();
5555 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5556 return getAIXFuncEntryPointSymbolSDNode(
F);
5562 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5570 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5577 assert(Callee.getNode() &&
"What no callee?");
5583 "Expected a CALLSEQ_STARTSDNode.");
5600 SDValue MTCTROps[] = {Chain, Callee, Glue};
5601 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5642 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5657 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5661 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5662 Alignment, MMOFlags);
5669 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5676 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5688 "Nest parameter is not supported on AIX.");
5704 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5707 const bool IsPPC64 = Subtarget.
isPPC64();
5709 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5756 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5758 RegsToPass[i].second.getValueType()));
5775 assert(Mask &&
"Missing call preserved mask for calling convention");
5783SDValue PPCTargetLowering::FinishCall(
5798 if (!CFlags.IsIndirect)
5802 dl, CFlags.HasNest, Subtarget);
5812 if (CFlags.IsTailCall) {
5816 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5819 isa<ConstantSDNode>(Callee) ||
5821 "Expecting a global address, external symbol, absolute value, "
5822 "register or an indirect tail call when PC Relative calls are "
5826 "Unexpected call opcode for a tail call.");
5833 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5834 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5846 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5849 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5860 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5869 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5870 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5874bool PPCTargetLowering::isEligibleForTCO(
5879 bool isCalleeExternalSymbol)
const {
5884 return IsEligibleForTailCallOptimization_64SVR4(
5885 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5886 isCalleeExternalSymbol);
5888 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5911 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5913 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5916 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5930 isa<GlobalAddressSDNode>(Callee)) &&
5931 "Callee should be an llvm::Function object.");
5934 <<
"\nTCO callee: ");
5941 "site marked musttail");
5946 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5948 Callee = LowerGlobalAddress(Callee, DAG);
5951 CallConv, isTailCall, isVarArg, isPatchPoint,
5959 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5964 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5966 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5970SDValue PPCTargetLowering::LowerCall_32SVR4(
5981 const bool IsVarArg = CFlags.IsVarArg;
5982 const bool IsTailCall = CFlags.IsTailCall;
5988 const Align PtrAlign(4);
6013 CCInfo.PreAnalyzeCallOperands(Outs);
6019 unsigned NumArgs = Outs.
size();
6021 for (
unsigned i = 0; i != NumArgs; ++i) {
6022 MVT ArgVT = Outs[i].VT;
6026 if (Outs[i].IsFixed) {
6036 errs() <<
"Call operand #" << i <<
" has unhandled type "
6046 CCInfo.clearWasPPCF128();
6053 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6060 unsigned NumBytes = CCByValInfo.getStackSize();
6074 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6085 bool seenFloatArg =
false;
6090 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6092 ++i, ++RealArgIdx) {
6094 SDValue Arg = OutVals[RealArgIdx];
6097 if (
Flags.isByVal()) {
6102 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6125 Chain = CallSeqStart = NewCallSeqStart;
6144 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6151 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6175 if (!MemOpChains.
empty())
6181 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6182 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6183 RegsToPass[i].second, InGlue);
6191 SDValue Ops[] = { Chain, InGlue };
6203 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6204 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6209SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6221 return NewCallSeqStart;
6224SDValue PPCTargetLowering::LowerCall_64SVR4(
6233 unsigned NumOps = Outs.
size();
6234 bool IsSibCall =
false;
6238 unsigned PtrByteSize = 8;
6253 assert(!(IsFastCall && CFlags.IsVarArg) &&
6254 "fastcc not supported on varargs functions");
6261 unsigned NumBytes = LinkageSize;
6262 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6265 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6266 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6269 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6270 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6273 const unsigned NumGPRs = std::size(GPR);
6275 const unsigned NumVRs = std::size(VR);
6281 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6282 if (!HasParameterArea) {
6283 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6284 unsigned AvailableFPRs = NumFPRs;
6285 unsigned AvailableVRs = NumVRs;
6286 unsigned NumBytesTmp = NumBytes;
6287 for (
unsigned i = 0; i != NumOps; ++i) {
6288 if (Outs[i].
Flags.isNest())
continue;
6290 PtrByteSize, LinkageSize, ParamAreaSize,
6291 NumBytesTmp, AvailableFPRs, AvailableVRs))
6292 HasParameterArea =
true;
6298 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6303 HasParameterArea =
false;
6306 for (
unsigned i = 0; i != NumOps; ++i) {
6308 EVT ArgVT = Outs[i].VT;
6309 EVT OrigVT = Outs[i].ArgVT;
6315 if (
Flags.isByVal()) {
6316 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6317 if (NumGPRsUsed > NumGPRs)
6318 HasParameterArea =
true;
6325 if (++NumGPRsUsed <= NumGPRs)
6335 if (++NumVRsUsed <= NumVRs)
6339 if (++NumVRsUsed <= NumVRs)
6344 if (++NumFPRsUsed <= NumFPRs)
6348 HasParameterArea =
true;
6355 NumBytes =
alignTo(NumBytes, Alignement);
6358 if (
Flags.isInConsecutiveRegsLast())
6359 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6362 unsigned NumBytesActuallyUsed = NumBytes;
6372 if (HasParameterArea)
6373 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6375 NumBytes = LinkageSize;
6390 if (CFlags.IsTailCall)
6402 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6413 unsigned ArgOffset = LinkageSize;
6419 for (
unsigned i = 0; i != NumOps; ++i) {
6422 EVT ArgVT = Outs[i].VT;
6423 EVT OrigVT = Outs[i].ArgVT;
6432 auto ComputePtrOff = [&]() {
6436 ArgOffset =
alignTo(ArgOffset, Alignment);
6447 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6448 GPR_idx = std::min(GPR_idx, NumGPRs);
6455 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6461 if (
Flags.isByVal()) {
6479 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6480 if (GPR_idx != NumGPRs) {
6484 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6486 ArgOffset += PtrByteSize;
6491 if (GPR_idx == NumGPRs &&
Size < 8) {
6493 if (!isLittleEndian) {
6498 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6501 ArgOffset += PtrByteSize;
6510 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6511 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6516 if (
Size < 8 && GPR_idx != NumGPRs) {
6526 if (!isLittleEndian) {
6530 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6538 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6541 ArgOffset += PtrByteSize;
6547 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6550 if (GPR_idx != NumGPRs) {
6551 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6557 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6558 ArgOffset += PtrByteSize;
6560 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6572 if (
Flags.isNest()) {
6574 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6581 if (GPR_idx != NumGPRs) {
6582 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6587 assert(HasParameterArea &&
6588 "Parameter area must exist to pass an argument in memory.");
6590 true, CFlags.IsTailCall,
false, MemOpChains,
6591 TailCallArguments, dl);
6593 ArgOffset += PtrByteSize;
6596 ArgOffset += PtrByteSize;
6609 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6610 bool NeededLoad =
false;
6613 if (FPR_idx != NumFPRs)
6614 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6617 if (!NeedGPROrStack)
6619 else if (GPR_idx != NumGPRs && !IsFastCall) {
6633 }
else if (!
Flags.isInConsecutiveRegs()) {
6639 }
else if (ArgOffset % PtrByteSize != 0) {
6643 if (!isLittleEndian)
6648 }
else if (
Flags.isInConsecutiveRegsLast()) {
6651 if (!isLittleEndian)
6661 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6669 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6674 assert(HasParameterArea &&
6675 "Parameter area must exist to pass an argument in memory.");
6677 true, CFlags.IsTailCall,
false, MemOpChains,
6678 TailCallArguments, dl);
6685 if (!IsFastCall || NeededLoad) {
6687 Flags.isInConsecutiveRegs()) ? 4 : 8;
6688 if (
Flags.isInConsecutiveRegsLast())
6689 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6709 if (CFlags.IsVarArg) {
6710 assert(HasParameterArea &&
6711 "Parameter area must exist if we have a varargs call.");
6717 if (VR_idx != NumVRs) {
6721 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6724 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6725 if (GPR_idx == NumGPRs)
6732 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6738 if (VR_idx != NumVRs) {
6739 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6744 assert(HasParameterArea &&
6745 "Parameter area must exist to pass an argument in memory.");
6747 true, CFlags.IsTailCall,
true, MemOpChains,
6748 TailCallArguments, dl);
6759 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6760 "mismatch in size of parameter area");
6761 (void)NumBytesActuallyUsed;
6763 if (!MemOpChains.
empty())
6769 if (CFlags.IsIndirect) {
6773 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6788 if (isELFv2ABI && !CFlags.IsPatchPoint)
6789 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6795 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6796 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6797 RegsToPass[i].second, InGlue);
6801 if (CFlags.IsTailCall && !IsSibCall)
6805 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6806 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6813 "Required alignment greater than stack alignment.");
6833 return RequiredAlign <= 8;
6838 return RequiredAlign <= 4;
6848 const bool IsPPC64 = Subtarget.
isPPC64();
6849 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6850 const Align PtrAlign(PtrSize);
6851 const Align StackAlign(16);
6852 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6854 if (ValVT == MVT::f128)
6861 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6862 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6864 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6865 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6868 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6869 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6870 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6876 if (ByValAlign > StackAlign)
6878 "16 are not supported.");
6881 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6885 if (ByValSize == 0) {
6893 while (NextReg != GPRs.
size() &&
6899 assert(Reg &&
"Alocating register unexpectedly failed.");
6904 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6925 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6954 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6956 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6989 const unsigned VecSize = 16;
6990 const Align VecAlign(VecSize);
7010 while (NextRegIndex != GPRs.
size() &&
7015 assert(Reg &&
"Allocating register unexpectedly failed.");
7028 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7040 if (NextRegIndex == GPRs.
size()) {
7049 if (GPRs[NextRegIndex] == PPC::R9) {
7054 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
7055 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
7056 assert(FirstReg && SecondReg &&
7057 "Allocating R9 or R10 unexpectedly failed.");
7071 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7073 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7088 assert((IsPPC64 || SVT != MVT::i64) &&
7089 "i64 should have been split for 32-bit codegen.");
7097 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7099 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7101 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7109 return &PPC::VRRCRegClass;
7122 else if (Flags.isZExt())
7132 if (PPC::GPRCRegClass.
contains(Reg)) {
7133 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7134 "Reg must be a valid argument register!");
7135 return LASize + 4 * (Reg - PPC::R3);
7138 if (PPC::G8RCRegClass.
contains(Reg)) {
7139 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7140 "Reg must be a valid argument register!");
7141 return LASize + 8 * (Reg - PPC::X3);
7187SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7194 "Unexpected calling convention!");
7204 const bool IsPPC64 = Subtarget.
isPPC64();
7205 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7217 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7218 uint64_t SaveStackPos = CCInfo.getStackSize();
7220 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7240 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7242 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7254 unsigned StoreSize =
7256 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7259 auto HandleMemLoc = [&]() {
7262 assert((ValSize <= LocSize) &&
7263 "Object size is larger than size of MemLoc");
7266 if (LocSize > ValSize)
7267 CurArgOffset += LocSize - ValSize;
7269 const bool IsImmutable =
7284 assert(isVarArg &&
"Only use custom memloc for vararg.");
7287 const unsigned OriginalValNo = VA.
getValNo();
7288 (void)OriginalValNo;
7290 auto HandleCustomVecRegLoc = [&]() {
7291 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7292 "Missing custom RegLoc.");
7295 "Unexpected Val type for custom RegLoc.");
7297 "ValNo mismatch between custom MemLoc and RegLoc.");
7301 Subtarget.hasVSX()));
7308 HandleCustomVecRegLoc();
7309 HandleCustomVecRegLoc();
7313 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7315 "Only 2 custom RegLocs expected for 64-bit codegen.");
7316 HandleCustomVecRegLoc();
7317 HandleCustomVecRegLoc();
7361 const unsigned Size =
7373 if (
Flags.isByVal()) {
7379 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7388 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7390 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7403 CopyFrom.
getValue(1), dl, CopyFrom,
7413 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7416 "RegLocs should be for ByVal argument.");
7423 if (
Offset != StackSize) {
7425 "Expected MemLoc for remaining bytes.");
7426 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7440 Subtarget.hasVSX()));
7457 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7459 unsigned CallerReservedArea = std::max<unsigned>(
7460 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7466 CallerReservedArea =
7475 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7476 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7478 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7479 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7480 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7485 for (
unsigned GPRIndex =
7486 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7487 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7490 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7491 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7503 if (!MemOps.
empty())
7509SDValue PPCTargetLowering::LowerCall_AIX(
7522 "Unexpected calling convention!");
7524 if (CFlags.IsPatchPoint)
7531 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7539 const bool IsPPC64 = Subtarget.
isPPC64();
7541 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7542 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7543 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7551 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7552 const unsigned NumBytes = std::max<unsigned>(
7553 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7569 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7570 const unsigned ValNo = ArgLocs[
I].getValNo();
7574 if (
Flags.isByVal()) {
7575 const unsigned ByValSize =
Flags.getByValSize();
7583 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7592 unsigned LoadOffset = 0;
7595 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7598 LoadOffset += PtrByteSize;
7601 "Unexpected location for pass-by-value argument.");
7605 if (LoadOffset == ByValSize)
7609 assert(ArgLocs[
I].getValNo() == ValNo &&
7610 "Expected additional location for by-value argument.");
7612 if (ArgLocs[
I].isMemLoc()) {
7613 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7618 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7624 CallSeqStart, MemcpyFlags, DAG, dl);
7633 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7634 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7635 "Unexpected register residue for by-value argument.");
7637 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7641 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7651 "Unexpected load emitted during handling of pass-by-value "
7659 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7694 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7702 const unsigned OriginalValNo = VA.
getValNo();
7704 unsigned LoadOffset = 0;
7705 auto HandleCustomVecRegLoc = [&]() {
7706 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7707 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7708 "Expected custom RegLoc.");
7711 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7717 LoadOffset += PtrByteSize;
7723 HandleCustomVecRegLoc();
7724 HandleCustomVecRegLoc();
7726 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7727 ArgLocs[
I].getValNo() == OriginalValNo) {
7729 "Only 2 custom RegLocs expected for 64-bit codegen.");
7730 HandleCustomVecRegLoc();
7731 HandleCustomVecRegLoc();
7749 "Unexpected register handling for calling convention.");
7755 "Custom register handling only expected for VarArg.");
7773 "Unexpected custom register for argument!");
7794 if (!MemOpChains.
empty())
7799 if (CFlags.IsIndirect) {
7800 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7803 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7804 const unsigned TOCSaveOffset =
7820 for (
auto Reg : RegsToPass) {
7825 const int SPDiff = 0;
7826 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7827 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7836 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7837 return CCInfo.CheckReturn(
7852 CCInfo.AnalyzeReturn(Outs,
7861 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7865 SDValue Arg = OutVals[RealResIdx];
7880 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7903 RetOps.push_back(Glue);
7909PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7914 EVT IntVT =
Op.getValueType();
7918 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7920 SDValue Ops[2] = {Chain, FPSIdx};
7934 bool isPPC64 = Subtarget.
isPPC64();
7935 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7955 bool isPPC64 = Subtarget.
isPPC64();
7976PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7978 bool isPPC64 = Subtarget.
isPPC64();
8012 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8013 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8024 bool isPPC64 = Subtarget.
isPPC64();
8036 Op.getOperand(0),
Op.getOperand(1));
8043 Op.getOperand(0),
Op.getOperand(1));
8047 if (
Op.getValueType().isVector())
8048 return LowerVectorLoad(
Op, DAG);
8050 assert(
Op.getValueType() == MVT::i1 &&
8051 "Custom lowering only for i1 loads");
8064 BasePtr, MVT::i8, MMO);
8072 if (
Op.getOperand(1).getValueType().isVector())
8073 return LowerVectorStore(
Op, DAG);
8075 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8076 "Custom lowering only for i1 stores");
8095 assert(
Op.getValueType() == MVT::i1 &&
8096 "Custom lowering only for i1 results");
8124 EVT TrgVT =
Op.getValueType();
8137 !llvm::has_single_bit<uint32_t>(
8148 if (SrcSize == 256) {
8159 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8167 for (
unsigned i = 0; i < TrgNumElts; ++i)
8170 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8174 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8187 EVT ResVT =
Op.getValueType();
8188 EVT CmpVT =
Op.getOperand(0).getValueType();
8190 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8196 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8213 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8245 if (
LHS.getValueType() == MVT::f32)
8258 if (
LHS.getValueType() == MVT::f32)
8267 if (
LHS.getValueType() == MVT::f32)
8281 if (
Cmp.getValueType() == MVT::f32)
8291 if (
Cmp.getValueType() == MVT::f32)
8297 if (
Cmp.getValueType() == MVT::f32)
8303 if (
Cmp.getValueType() == MVT::f32)
8309 if (
Cmp.getValueType() == MVT::f32)
8342 bool IsStrict =
Op->isStrictFPOpcode();
8348 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8351 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8353 MVT DestTy =
Op.getSimpleValueType();
8354 assert(Src.getValueType().isFloatingPoint() &&
8355 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8356 DestTy == MVT::i64) &&
8357 "Invalid FP_TO_INT types");
8358 if (Src.getValueType() == MVT::f32) {
8362 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8363 Chain = Src.getValue(1);
8367 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8368 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8377 assert((IsSigned || Subtarget.hasFPCVT()) &&
8378 "i64 FP_TO_UINT is supported only with FPCVT");
8381 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8385 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8388 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8393void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8395 const SDLoc &dl)
const {
8399 bool IsStrict =
Op->isStrictFPOpcode();
8402 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8403 (IsSigned || Subtarget.hasFPCVT());
8405 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8414 Alignment =
Align(4);
8417 SDValue Ops[] = { Chain, Tmp, FIPtr };
8419 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8421 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8425 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8434 RLI.Alignment = Alignment;
8442 const SDLoc &dl)
const {
8445 if (
Op->isStrictFPOpcode())
8452 const SDLoc &dl)
const {
8453 bool IsStrict =
Op->isStrictFPOpcode();
8456 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8457 EVT SrcVT = Src.getValueType();
8458 EVT DstVT =
Op.getValueType();
8461 if (SrcVT == MVT::f128)
8462 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8466 if (SrcVT == MVT::ppcf128) {
8467 if (DstVT == MVT::i32) {
8472 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8483 {Op.getOperand(0), Lo, Hi}, Flags);
8486 {Res.getValue(1), Res}, Flags);
8492 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8516 {Chain, Src, FltOfs}, Flags);
8520 {Chain, Val}, Flags);
8523 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8541 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8542 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8545 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8547 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8548 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8559bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8564 if (
Op->isStrictFPOpcode())
8569 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8573 Op.getOperand(0).getValueType())) {
8575 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8580 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8581 LD->isNonTemporal())
8583 if (
LD->getMemoryVT() != MemVT)
8593 RLI.Ptr =
LD->getBasePtr();
8594 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8596 "Non-pre-inc AM on PPC?");
8601 RLI.Chain =
LD->getChain();
8602 RLI.MPI =
LD->getPointerInfo();
8603 RLI.IsDereferenceable =
LD->isDereferenceable();
8604 RLI.IsInvariant =
LD->isInvariant();
8605 RLI.Alignment =
LD->getAlign();
8606 RLI.AAInfo =
LD->getAAInfo();
8607 RLI.Ranges =
LD->getRanges();
8609 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8617void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8623 SDLoc dl(NewResChain);
8626 NewResChain, DAG.
getUNDEF(MVT::Other));
8628 "A new TF really is required here");
8637bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8638 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8645 if (!Subtarget.hasP9Vector() &&
8654 if (UI.getUse().get().getResNo() != 0)
8676 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8680 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8683 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8684 if (
Op->isStrictFPOpcode()) {
8686 Chain =
Op.getOperand(0);
8688 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8690 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8698 const SDLoc &dl)
const {
8699 assert((
Op.getValueType() == MVT::f32 ||
8700 Op.getValueType() == MVT::f64) &&
8701 "Invalid floating point type as target of conversion");
8702 assert(Subtarget.hasFPCVT() &&
8703 "Int to FP conversions with direct moves require FPCVT");
8704 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8705 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8727 for (
unsigned i = 1; i < NumConcat; ++i)
8734 const SDLoc &dl)
const {
8735 bool IsStrict =
Op->isStrictFPOpcode();
8736 unsigned Opc =
Op.getOpcode();
8737 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8740 "Unexpected conversion type");
8741 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8742 "Supports conversions to v2f64/v4f32 only.");
8746 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8749 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8754 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8757 for (
unsigned i = 0; i < WideNumElts; ++i)
8760 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8761 int SaveElts = FourEltRes ? 4 : 2;
8763 for (
int i = 0; i < SaveElts; i++)
8764 ShuffV[i * Stride] = i;
8766 for (
int i = 1; i <= SaveElts; i++)
8767 ShuffV[i * Stride - 1] = i - 1;
8775 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8776 EVT ExtVT = Src.getValueType();
8777 if (Subtarget.hasP9Altivec())
8788 {Op.getOperand(0), Extend}, Flags);
8790 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8798 bool IsStrict =
Op->isStrictFPOpcode();
8799 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8804 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8806 EVT InVT = Src.getValueType();
8807 EVT OutVT =
Op.getValueType();
8810 return LowerINT_TO_FPVector(
Op, DAG, dl);
8813 if (
Op.getValueType() == MVT::f128)
8814 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8817 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8820 if (Src.getValueType() == MVT::i1) {
8832 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8833 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8834 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8836 assert((IsSigned || Subtarget.hasFPCVT()) &&
8837 "UINT_TO_FP is supported only with FPCVT");
8839 if (Src.getValueType() == MVT::i64) {
8851 if (
Op.getValueType() == MVT::f32 &&
8852 !Subtarget.hasFPCVT() &&
8893 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8894 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8895 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8896 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8897 }
else if (Subtarget.hasLFIWAX() &&
8898 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8901 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8902 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8905 Ops, MVT::i32, MMO);
8906 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8907 }
else if (Subtarget.hasFPCVT() &&
8908 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8911 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8912 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8915 Ops, MVT::i32, MMO);
8916 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8917 }
else if (((Subtarget.hasLFIWAX() &&
8919 (Subtarget.hasFPCVT() &&
8933 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8934 "Expected an i32 store");
8940 RLI.Alignment =
Align(4);
8944 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8945 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8948 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8949 Ops, MVT::i32, MMO);
8950 Chain =
Bits.getValue(1);
8956 Chain =
FP.getValue(1);
8958 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8962 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8970 assert(Src.getValueType() == MVT::i32 &&
8971 "Unhandled INT_TO_FP type in custom expander!");
8981 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8984 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8993 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8994 "Expected an i32 store");
9000 RLI.Alignment =
Align(4);
9005 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9006 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9008 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9012 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
9015 "i32->FP without LFIWAX supported only on PPC64");
9024 Chain, dl, Ext64, FIdx,
9030 MVT::f64, dl, Chain, FIdx,
9038 Chain =
FP.getValue(1);
9039 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9043 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
9074 EVT VT =
Op.getValueType();
9080 Chain =
MFFS.getValue(1);
9094 "Stack slot adjustment is valid only on big endian subtargets!");
9124 EVT VT =
Op.getValueType();
9128 VT ==
Op.getOperand(1).getValueType() &&
9148 SDValue OutOps[] = { OutLo, OutHi };
9153 EVT VT =
Op.getValueType();
9157 VT ==
Op.getOperand(1).getValueType() &&
9177 SDValue OutOps[] = { OutLo, OutHi };
9183 EVT VT =
Op.getValueType();
9186 VT ==
Op.getOperand(1).getValueType() &&
9206 SDValue OutOps[] = { OutLo, OutHi };
9213 EVT VT =
Op.getValueType();
9220 EVT AmtVT =
Z.getValueType();
9243 static const MVT VTys[] = {
9244 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9247 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9250 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9255 EVT CanonicalVT = VTys[SplatSize-1];
9264 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9265 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9274 EVT DestVT = MVT::Other) {
9275 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9284 EVT DestVT = MVT::Other) {
9287 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9299 for (
unsigned i = 0; i != 16; ++i)
9320 EVT VecVT = V->getValueType(0);
9321 bool RightType = VecVT == MVT::v2f64 ||
9322 (HasP8Vector && VecVT == MVT::v4f32) ||
9323 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9327 bool IsSplat =
true;
9328 bool IsLoad =
false;
9329 SDValue Op0 = V->getOperand(0);
9334 if (V->isConstant())
9336 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9337 if (V->getOperand(i).isUndef())
9341 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9343 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9345 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9347 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9351 if (V->getOperand(i) != Op0 ||
9352 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9355 return !(IsSplat && IsLoad);
9364 if ((
Op.getValueType() != MVT::f128) ||
9385 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9393 APFloat APFloatToConvert = ArgAPFloat;
9394 bool LosesInfo =
true;
9399 ArgAPFloat = APFloatToConvert;
9421 APFloat APFloatToConvert = ArgAPFloat;
9422 bool LosesInfo =
true;
9426 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9431 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9435 EVT Ty =
Op->getValueType(0);
9438 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9447 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9451 if (Ty == MVT::v2i64) {
9454 if (MemVT == MVT::i32) {
9474 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9477 APInt APSplatBits, APSplatUndef;
9478 unsigned SplatBitSize;
9480 bool BVNIsConstantSplat =
9488 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9489 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9492 if ((
Op->getValueType(0) == MVT::v2f64) &&
9527 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9534 const SDValue *InputLoad = &
Op.getOperand(0);
9539 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9540 unsigned ElementSize =
9543 assert(((ElementSize == 2 * MemorySize)
9547 "Unmatched element size and opcode!\n");
9552 unsigned NumUsesOfInputLD = 128 / ElementSize;
9554 if (BVInOp.isUndef())
9569 if (NumUsesOfInputLD == 1 &&
9572 Subtarget.hasLFIWAX()))
9581 Subtarget.isISA3_1() && ElementSize <= 16)
9584 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9586 Subtarget.hasVSX()) {
9593 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9594 LD->getMemoryVT(),
LD->getMemOperand());
9606 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9608 Subtarget.hasP8Vector()))
9615 unsigned SplatSize = SplatBitSize / 8;
9620 if (SplatBits == 0) {
9622 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9634 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9636 Op.getValueType(), DAG, dl);
9638 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9643 if (Subtarget.hasP9Vector() && SplatSize == 1)
9648 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9650 if (SextVal >= -16 && SextVal <= 15)
9663 if (SextVal >= -32 && SextVal <= 31) {
9668 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9669 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9672 if (VT ==
Op.getValueType())
9681 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9695 static const signed char SplatCsts[] = {
9696 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9697 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9700 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9703 int i = SplatCsts[idx];
9707 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9710 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9712 static const unsigned IIDs[] = {
9713 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9714 Intrinsic::ppc_altivec_vslw
9721 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9723 static const unsigned IIDs[] = {
9724 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9725 Intrinsic::ppc_altivec_vsrw
9732 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9733 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9735 static const unsigned IIDs[] = {
9736 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9737 Intrinsic::ppc_altivec_vrlw
9744 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9750 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9756 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9771 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9772 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9773 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9789 if (LHSID == (1*9+2)*9+3)
return LHS;
9790 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9802 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9803 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9804 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9805 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9808 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9809 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9810 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9811 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9814 for (
unsigned i = 0; i != 16; ++i)
9815 ShufIdxs[i] = (i&3)+0;
9818 for (
unsigned i = 0; i != 16; ++i)
9819 ShufIdxs[i] = (i&3)+4;
9822 for (
unsigned i = 0; i != 16; ++i)
9823 ShufIdxs[i] = (i&3)+8;
9826 for (
unsigned i = 0; i != 16; ++i)
9827 ShufIdxs[i] = (i&3)+12;
9848 const unsigned BytesInVector = 16;
9853 unsigned ShiftElts = 0, InsertAtByte = 0;
9857 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9858 0, 15, 14, 13, 12, 11, 10, 9};
9859 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9860 1, 2, 3, 4, 5, 6, 7, 8};
9863 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9875 bool FoundCandidate =
false;
9879 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9882 for (
unsigned i = 0; i < BytesInVector; ++i) {
9883 unsigned CurrentElement =
Mask[i];
9886 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9889 bool OtherElementsInOrder =
true;
9892 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9899 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9900 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9901 OtherElementsInOrder =
false;
9908 if (OtherElementsInOrder) {
9915 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9916 : BigEndianShifts[CurrentElement & 0xF];
9917 Swap = CurrentElement < BytesInVector;
9919 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9920 FoundCandidate =
true;
9925 if (!FoundCandidate)
9949 const unsigned NumHalfWords = 8;
9950 const unsigned BytesInVector = NumHalfWords * 2;
9959 unsigned ShiftElts = 0, InsertAtByte = 0;
9963 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9964 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9967 uint32_t OriginalOrderLow = 0x1234567;
9968 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9971 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9972 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9989 bool FoundCandidate =
false;
9992 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9993 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10001 if (
V2.isUndef()) {
10003 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10004 TargetOrder = OriginalOrderLow;
10008 if (MaskOneElt == VINSERTHSrcElem &&
10009 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10010 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10011 FoundCandidate =
true;
10017 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10019 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10021 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10022 : BigEndianShifts[MaskOneElt & 0x7];
10023 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10024 Swap = MaskOneElt < NumHalfWords;
10025 FoundCandidate =
true;
10031 if (!FoundCandidate)
10066 auto ShuffleMask = SVN->
getMask();
10081 ShuffleMask = CommutedSV->
getMask();
10090 APInt APSplatValue, APSplatUndef;
10091 unsigned SplatBitSize;
10107 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10108 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10109 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10111 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10112 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10113 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10121 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10122 SplatVal |= (SplatVal << SplatBitSize);
10136 assert(
Op.getValueType() == MVT::v1i128 &&
10137 "Only set v1i128 as custom, other type shouldn't reach here!");
10142 if (SHLAmt % 8 == 0) {
10143 std::array<int, 16>
Mask;
10144 std::iota(
Mask.begin(),
Mask.end(), 0);
10145 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10174 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10175 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10178 SVOp = cast<ShuffleVectorSDNode>(
Op);
10179 V1 =
Op.getOperand(0);
10180 V2 =
Op.getOperand(1);
10182 EVT VT =
Op.getValueType();
10185 unsigned ShiftElts, InsertAtByte;
10191 bool IsPermutedLoad =
false;
10193 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10203 if (IsPermutedLoad) {
10204 assert((isLittleEndian || IsFourByte) &&
10205 "Unexpected size for permuted load on big endian target");
10206 SplatIdx += IsFourByte ? 2 : 1;
10207 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10208 "Splat of a value outside of the loaded memory");
10213 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10216 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10218 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10222 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10235 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10238 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10247 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10250 if (Subtarget.hasP9Vector() &&
10271 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10273 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10274 return SplatInsertNode;
10277 if (Subtarget.hasP9Altivec()) {
10279 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10282 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10286 if (Subtarget.hasVSX() &&
10299 if (Subtarget.hasVSX() &&
10312 if (Subtarget.hasP9Vector()) {
10332 if (Subtarget.hasVSX()) {
10353 if (
V2.isUndef()) {
10366 (Subtarget.hasP8Altivec() && (
10377 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10387 (Subtarget.hasP8Altivec() && (
10398 unsigned PFIndexes[4];
10399 bool isFourElementShuffle =
true;
10400 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10402 unsigned EltNo = 8;
10403 for (
unsigned j = 0;
j != 4; ++
j) {
10404 if (PermMask[i * 4 + j] < 0)
10407 unsigned ByteSource = PermMask[i * 4 +
j];
10408 if ((ByteSource & 3) != j) {
10409 isFourElementShuffle =
false;
10414 EltNo = ByteSource / 4;
10415 }
else if (EltNo != ByteSource / 4) {
10416 isFourElementShuffle =
false;
10420 PFIndexes[i] = EltNo;
10428 if (isFourElementShuffle) {
10430 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10431 PFIndexes[2] * 9 + PFIndexes[3];
10434 unsigned Cost = (PFEntry >> 30);
10454 if (
V2.isUndef())
V2 = V1;
10456 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10465 bool NeedSwap =
false;
10467 bool isPPC64 = Subtarget.
isPPC64();
10469 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10471 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10472 "XXPERM instead\n");
10478 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10479 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10481 NeedSwap = !NeedSwap;
10516 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10518 if (V1HasXXSWAPD) {
10521 else if (SrcElt < 16)
10524 if (V2HasXXSWAPD) {
10527 else if (SrcElt > 15)
10536 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10537 if (isLittleEndian)
10539 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10542 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10545 if (V1HasXXSWAPD) {
10549 if (V2HasXXSWAPD) {
10550 dl =
SDLoc(
V2->getOperand(0));
10551 V2 =
V2->getOperand(0)->getOperand(1);
10554 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10555 if (ValType != MVT::v2f64)
10557 if (
V2.getValueType() != MVT::v2f64)
10561 ShufflesHandledWithVPERM++;
10566 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10568 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10571 dbgs() <<
"With the following permute control vector:\n";
10576 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10580 if (isLittleEndian)
10586 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10598 switch (IntrinsicID) {
10602 case Intrinsic::ppc_altivec_vcmpbfp_p:
10606 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10610 case Intrinsic::ppc_altivec_vcmpequb_p:
10614 case Intrinsic::ppc_altivec_vcmpequh_p:
10618 case Intrinsic::ppc_altivec_vcmpequw_p:
10622 case Intrinsic::ppc_altivec_vcmpequd_p:
10623 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10629 case Intrinsic::ppc_altivec_vcmpneb_p:
10630 case Intrinsic::ppc_altivec_vcmpneh_p:
10631 case Intrinsic::ppc_altivec_vcmpnew_p:
10632 case Intrinsic::ppc_altivec_vcmpnezb_p:
10633 case Intrinsic::ppc_altivec_vcmpnezh_p:
10634 case Intrinsic::ppc_altivec_vcmpnezw_p:
10635 if (Subtarget.hasP9Altivec()) {
10636 switch (IntrinsicID) {
10639 case Intrinsic::ppc_altivec_vcmpneb_p:
10642 case Intrinsic::ppc_altivec_vcmpneh_p:
10645 case Intrinsic::ppc_altivec_vcmpnew_p:
10648 case Intrinsic::ppc_altivec_vcmpnezb_p:
10651 case Intrinsic::ppc_altivec_vcmpnezh_p:
10654 case Intrinsic::ppc_altivec_vcmpnezw_p:
10662 case Intrinsic::ppc_altivec_vcmpgefp_p:
10666 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10670 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10674 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10678 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10682 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10683 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10689 case Intrinsic::ppc_altivec_vcmpgtub_p:
10693 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10697 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10701 case Intrinsic::ppc_altivec_vcmpgtud_p:
10702 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10709 case Intrinsic::ppc_altivec_vcmpequq:
10710 case Intrinsic::ppc_altivec_vcmpgtsq:
10711 case Intrinsic::ppc_altivec_vcmpgtuq:
10712 if (!Subtarget.isISA3_1())
10714 switch (IntrinsicID) {
10717 case Intrinsic::ppc_altivec_vcmpequq:
10720 case Intrinsic::ppc_altivec_vcmpgtsq:
10723 case Intrinsic::ppc_altivec_vcmpgtuq:
10730 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10731 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10732 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10733 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10734 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10735 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10736 if (Subtarget.hasVSX()) {
10737 switch (IntrinsicID) {
10738 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10741 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10744 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10747 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10750 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10753 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10763 case Intrinsic::ppc_altivec_vcmpbfp:
10766 case Intrinsic::ppc_altivec_vcmpeqfp:
10769 case Intrinsic::ppc_altivec_vcmpequb:
10772 case Intrinsic::ppc_altivec_vcmpequh:
10775 case Intrinsic::ppc_altivec_vcmpequw:
10778 case Intrinsic::ppc_altivec_vcmpequd:
10779 if (Subtarget.hasP8Altivec())
10784 case Intrinsic::ppc_altivec_vcmpneb:
10785 case Intrinsic::ppc_altivec_vcmpneh:
10786 case Intrinsic::ppc_altivec_vcmpnew:
10787 case Intrinsic::ppc_altivec_vcmpnezb:
10788 case Intrinsic::ppc_altivec_vcmpnezh:
10789 case Intrinsic::ppc_altivec_vcmpnezw:
10790 if (Subtarget.hasP9Altivec())
10791 switch (IntrinsicID) {
10794 case Intrinsic::ppc_altivec_vcmpneb:
10797 case Intrinsic::ppc_altivec_vcmpneh:
10800 case Intrinsic::ppc_altivec_vcmpnew:
10803 case Intrinsic::ppc_altivec_vcmpnezb:
10806 case Intrinsic::ppc_altivec_vcmpnezh:
10809 case Intrinsic::ppc_altivec_vcmpnezw:
10816 case Intrinsic::ppc_altivec_vcmpgefp:
10819 case Intrinsic::ppc_altivec_vcmpgtfp:
10822 case Intrinsic::ppc_altivec_vcmpgtsb:
10825 case Intrinsic::ppc_altivec_vcmpgtsh:
10828 case Intrinsic::ppc_altivec_vcmpgtsw:
10831 case Intrinsic::ppc_altivec_vcmpgtsd:
10832 if (Subtarget.hasP8Altivec())
10837 case Intrinsic::ppc_altivec_vcmpgtub:
10840 case Intrinsic::ppc_altivec_vcmpgtuh:
10843 case Intrinsic::ppc_altivec_vcmpgtuw:
10846 case Intrinsic::ppc_altivec_vcmpgtud:
10847 if (Subtarget.hasP8Altivec())
10852 case Intrinsic::ppc_altivec_vcmpequq_p:
10853 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10854 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10855 if (!Subtarget.isISA3_1())
10857 switch (IntrinsicID) {
10860 case Intrinsic::ppc_altivec_vcmpequq_p:
10863 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10866 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10880 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10884 switch (IntrinsicID) {
10885 case Intrinsic::thread_pointer:
10891 case Intrinsic::ppc_rldimi: {
10892 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
10896 return Op.getOperand(2);
10897 if (
Mask.isAllOnes())
10900 unsigned MB = 0, ME = 0;
10904 if (ME < 63 - SH) {
10907 }
else if (ME > 63 - SH) {
10913 {Op.getOperand(2), Src,
10914 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
10915 DAG.getTargetConstant(MB, dl, MVT::i32)}),
10919 case Intrinsic::ppc_rlwimi: {
10922 return Op.getOperand(2);
10923 if (
Mask.isAllOnes())
10926 unsigned MB = 0, ME = 0;
10930 PPC::RLWIMI, dl, MVT::i32,
10931 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
10932 DAG.getTargetConstant(MB, dl, MVT::i32),
10933 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10937 case Intrinsic::ppc_rlwnm: {
10938 if (
Op.getConstantOperandVal(3) == 0)
10940 unsigned MB = 0, ME = 0;
10945 {Op.getOperand(1), Op.getOperand(2),
10946 DAG.getTargetConstant(MB, dl, MVT::i32),
10947 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10951 case Intrinsic::ppc_mma_disassemble_acc: {
10952 if (Subtarget.isISAFuture()) {
10953 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
10991 case Intrinsic::ppc_vsx_disassemble_pair: {
10994 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10999 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11010 case Intrinsic::ppc_mma_xxmfacc:
11011 case Intrinsic::ppc_mma_xxmtacc: {
11013 if (!Subtarget.isISAFuture())
11024 case Intrinsic::ppc_unpack_longdouble: {
11025 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11026 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11027 "Argument of long double unpack must be 0 or 1!");
11030 Idx->getValueType(0)));
11033 case Intrinsic::ppc_compare_exp_lt:
11034 case Intrinsic::ppc_compare_exp_gt:
11035 case Intrinsic::ppc_compare_exp_eq:
11036 case Intrinsic::ppc_compare_exp_uo: {
11038 switch (IntrinsicID) {
11039 case Intrinsic::ppc_compare_exp_lt:
11042 case Intrinsic::ppc_compare_exp_gt:
11045 case Intrinsic::ppc_compare_exp_eq:
11048 case Intrinsic::ppc_compare_exp_uo:
11054 PPC::SELECT_CC_I4, dl, MVT::i32,
11055 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11056 Op.getOperand(1), Op.getOperand(2)),
11058 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11059 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11062 case Intrinsic::ppc_test_data_class: {
11063 EVT OpVT =
Op.getOperand(1).getValueType();
11064 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11065 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11069 PPC::SELECT_CC_I4, dl, MVT::i32,
11070 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11073 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11074 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11077 case Intrinsic::ppc_fnmsub: {
11078 EVT VT =
Op.getOperand(1).getValueType();
11079 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11085 Op.getOperand(2),
Op.getOperand(3));
11087 case Intrinsic::ppc_convert_f128_to_ppcf128:
11088 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11089 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11090 ? RTLIB::CONVERT_PPCF128_F128
11091 : RTLIB::CONVERT_F128_PPCF128;
11092 MakeLibCallOptions CallOptions;
11093 std::pair<SDValue, SDValue>
Result =
11094 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11098 case Intrinsic::ppc_maxfe:
11099 case Intrinsic::ppc_maxfl:
11100 case Intrinsic::ppc_maxfs:
11101 case Intrinsic::ppc_minfe:
11102 case Intrinsic::ppc_minfl:
11103 case Intrinsic::ppc_minfs: {
11104 EVT VT =
Op.getValueType();
11107 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11108 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11111 if (IntrinsicID == Intrinsic::ppc_minfe ||
11112 IntrinsicID == Intrinsic::ppc_minfl ||
11113 IntrinsicID == Intrinsic::ppc_minfs)
11135 Op.getOperand(1),
Op.getOperand(2),
11146 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11158 switch (
Op.getConstantOperandVal(1)) {
11161 BitNo = 0; InvertBit =
false;
11164 BitNo = 0; InvertBit =
true;
11167 BitNo = 2; InvertBit =
false;
11170 BitNo = 2; InvertBit =
true;
11192 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11194 switch (
Op.getConstantOperandVal(ArgStart)) {
11195 case Intrinsic::ppc_cfence: {
11196 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11197 SDValue Val =
Op.getOperand(ArgStart + 1);
11199 if (Ty == MVT::i128) {
11204 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11205 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11229 int VectorIndex = 0;
11242 "Expecting an atomic compare-and-swap here.");
11244 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11245 EVT MemVT = AtomicNode->getMemoryVT();
11263 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11264 Ops.
push_back(AtomicNode->getOperand(i));
11276 EVT MemVT =
N->getMemoryVT();
11278 "Expect quadword atomic operations");
11280 unsigned Opc =
N->getOpcode();
11288 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11289 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11292 Ops, MemVT,
N->getMemOperand());
11299 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11309 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11319 N->getMemOperand());
11331 enum DataClassMask {
11333 DC_NEG_INF = 1 << 4,
11334 DC_POS_INF = 1 << 5,
11335 DC_NEG_ZERO = 1 << 2,
11336 DC_POS_ZERO = 1 << 3,
11337 DC_NEG_SUBNORM = 1,
11338 DC_POS_SUBNORM = 1 << 1,
11341 EVT VT =
Op.getValueType();
11343 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11344 : VT == MVT::f64 ? PPC::XSTSTDCDP
11355 return DAG.
getNOT(Dl, Rev, MVT::i1);
11362 TestOp, Dl, MVT::i32,
11364 DC_NEG_ZERO | DC_POS_ZERO |
11365 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11371 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11377 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11382 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11395 bool IsQuiet = Mask &
fcQNan;
11401 if (VT == MVT::f128) {
11405 QuietMask = 0x8000;
11406 }
else if (VT == MVT::f64) {
11418 QuietMask = 0x80000;
11419 }
else if (VT == MVT::f32) {
11421 QuietMask = 0x400000;
11437 unsigned NativeMask = 0;
11439 NativeMask |= DC_NAN;
11441 NativeMask |= DC_NEG_INF;
11443 NativeMask |= DC_POS_INF;
11445 NativeMask |= DC_NEG_ZERO;
11447 NativeMask |= DC_POS_ZERO;
11449 NativeMask |= DC_NEG_SUBNORM;
11451 NativeMask |= DC_POS_SUBNORM;
11454 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11456 TestOp, Dl, MVT::i32,
11465 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11467 uint64_t RHSC =
Op.getConstantOperandVal(1);
11492 "Should only be called for ISD::INSERT_VECTOR_ELT");
11496 EVT VT =
Op.getValueType();
11501 if (VT == MVT::v2f64 &&
C)
11504 if (Subtarget.hasP9Vector()) {
11513 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11514 (isa<LoadSDNode>(V2))) {
11519 BitcastLoad,
Op.getOperand(2));
11520 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11524 if (Subtarget.isISA3_1()) {
11525 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11529 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11530 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11540 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11543 unsigned InsertAtElement =
C->getZExtValue();
11544 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11546 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11560 EVT VT =
Op.getValueType();
11562 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11568 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11569 "Type unsupported without MMA");
11570 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11571 "Type unsupported without paired vector support");
11576 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11578 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11588 std::reverse(Loads.
begin(), Loads.
end());
11589 std::reverse(LoadChains.
begin(), LoadChains.
end());
11607 EVT StoreVT =
Value.getValueType();
11609 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11615 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11616 "Type unsupported without MMA");
11617 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11618 "Type unsupported without paired vector support");
11621 unsigned NumVecs = 2;
11622 if (StoreVT == MVT::v512i1) {
11623 if (Subtarget.isISAFuture()) {
11624 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11626 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11629 Value2 =
SDValue(ExtNode, 1);
11634 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11637 if (Subtarget.isISAFuture()) {
11647 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11661 if (
Op.getValueType() == MVT::v4i32) {
11678 LHS, RHS, DAG, dl, MVT::v4i32);
11681 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11686 }
else if (
Op.getValueType() == MVT::v16i8) {
11692 LHS, RHS, DAG, dl, MVT::v8i16);
11697 LHS, RHS, DAG, dl, MVT::v8i16);
11705 for (
unsigned i = 0; i != 8; ++i) {
11706 if (isLittleEndian) {
11708 Ops[i*2+1] = 2*i+16;
11711 Ops[i*2+1] = 2*i+1+16;
11714 if (isLittleEndian)
11724 bool IsStrict =
Op->isStrictFPOpcode();
11725 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11726 !Subtarget.hasP9Vector())
11736 "Should only be called for ISD::FP_EXTEND");
11740 if (
Op.getValueType() != MVT::v2f64 ||
11741 Op.getOperand(0).getValueType() != MVT::v2f32)
11753 "Node should have 2 operands with second one being a constant!");
11765 int DWord =
Idx >> 1;
11788 LD->getMemoryVT(),
LD->getMemOperand());
11801 LD->getMemoryVT(),
LD->getMemOperand());
11812 switch (
Op.getOpcode()) {
11841 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11867 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11868 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11880 return LowerFP_ROUND(
Op, DAG);
11893 return LowerINTRINSIC_VOID(
Op, DAG);
11895 return LowerBSWAP(
Op, DAG);
11897 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11899 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11901 return LowerIS_FPCLASS(
Op, DAG);
11909 switch (
N->getOpcode()) {
11911 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11928 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
11931 assert(
N->getValueType(0) == MVT::i1 &&
11932 "Unexpected result type for CTR decrement intrinsic");
11934 N->getValueType(0));
11944 switch (
N->getConstantOperandVal(0)) {
11945 case Intrinsic::ppc_pack_longdouble:
11947 N->getOperand(2),
N->getOperand(1)));
11949 case Intrinsic::ppc_maxfe:
11950 case Intrinsic::ppc_minfe:
11951 case Intrinsic::ppc_fnmsub:
11952 case Intrinsic::ppc_convert_f128_to_ppcf128:
11962 EVT VT =
N->getValueType(0);
11964 if (VT == MVT::i64) {
11977 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11981 Results.push_back(LoweredValue);
11982 if (
N->isStrictFPOpcode())
11987 if (!
N->getValueType(0).isVector())
12038 if (isa<LoadInst>(Inst))
12042 Intrinsic::ppc_cfence, {Inst->getType()}),
12052 unsigned AtomicSize,
12053 unsigned BinOpcode,
12054 unsigned CmpOpcode,
12055 unsigned CmpPred)
const {
12059 auto LoadMnemonic = PPC::LDARX;
12060 auto StoreMnemonic = PPC::STDCX;
12061 switch (AtomicSize) {
12065 LoadMnemonic = PPC::LBARX;
12066 StoreMnemonic = PPC::STBCX;
12067 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12070 LoadMnemonic = PPC::LHARX;
12071 StoreMnemonic = PPC::STHCX;
12072 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12075 LoadMnemonic = PPC::LWARX;
12076 StoreMnemonic = PPC::STWCX;
12079 LoadMnemonic = PPC::LDARX;
12080 StoreMnemonic = PPC::STDCX;
12096 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12098 F->insert(It, loopMBB);
12100 F->insert(It, loop2MBB);
12101 F->insert(It, exitMBB);
12107 Register TmpReg = (!BinOpcode) ? incr :
12109 : &PPC::GPRCRegClass);
12134 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12141 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12143 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12171 switch(
MI.getOpcode()) {
12175 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12176 &
MI.getMF()->getRegInfo());
12200 case PPC::EXTSB8_32_64:
12201 case PPC::EXTSB8_rec:
12202 case PPC::EXTSB_rec:
12205 case PPC::EXTSH8_32_64:
12206 case PPC::EXTSH8_rec:
12207 case PPC::EXTSH_rec:
12209 case PPC::EXTSWSLI:
12210 case PPC::EXTSWSLI_32_64:
12211 case PPC::EXTSWSLI_32_64_rec:
12212 case PPC::EXTSWSLI_rec:
12213 case PPC::EXTSW_32:
12214 case PPC::EXTSW_32_64:
12215 case PPC::EXTSW_32_64_rec:
12216 case PPC::EXTSW_rec:
12219 case PPC::SRAWI_rec:
12220 case PPC::SRAW_rec:
12229 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12239 bool IsSignExtended =
12242 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12244 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12245 .
addReg(
MI.getOperand(3).getReg());
12246 MI.getOperand(3).setReg(ValueReg);
12250 if (Subtarget.hasPartwordAtomics())
12258 bool is64bit = Subtarget.
isPPC64();
12260 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12271 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12273 F->insert(It, loopMBB);
12275 F->insert(It, loop2MBB);
12276 F->insert(It, exitMBB);
12282 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12327 if (ptrA != ZeroReg) {
12329 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12337 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12338 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12341 .
addImm(is8bit ? 28 : 27);
12342 if (!isLittleEndian)
12343 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12345 .
addImm(is8bit ? 24 : 16);
12347 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12352 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12362 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12366 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12371 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12375 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12378 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12390 unsigned ValueReg = SReg;
12391 unsigned CmpReg = Incr2Reg;
12392 if (CmpOpcode == PPC::CMPW) {
12394 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12398 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12400 ValueReg = ValueSReg;
12432 .
addImm(is8bit ? 24 : 16)
12453 Register DstReg =
MI.getOperand(0).getReg();
12455 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12456 Register mainDstReg =
MRI.createVirtualRegister(RC);
12457 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12460 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12461 "Invalid Pointer Size!");
12509 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12510 Register BufReg =
MI.getOperand(1).getReg();
12525 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12527 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12530 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12553 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12574 TII->get(PPC::PHI), DstReg)
12578 MI.eraseFromParent();
12592 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12593 "Invalid Pointer Size!");
12596 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12599 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12600 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12614 Register BufReg =
MI.getOperand(0).getReg();
12619 if (PVT == MVT::i64) {
12631 if (PVT == MVT::i64) {
12643 if (PVT == MVT::i64) {
12655 if (PVT == MVT::i64) {
12667 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12677 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12680 MI.eraseFromParent();
12696 "Unexpected stack alignment");
12700 unsigned StackProbeSize =
12703 StackProbeSize &= ~(StackAlign - 1);
12704 return StackProbeSize ? StackProbeSize : StackAlign;
12716 const bool isPPC64 = Subtarget.
isPPC64();
12748 MF->
insert(MBBIter, TestMBB);
12749 MF->
insert(MBBIter, BlockMBB);
12750 MF->
insert(MBBIter, TailMBB);
12755 Register DstReg =
MI.getOperand(0).getReg();
12756 Register NegSizeReg =
MI.getOperand(1).getReg();
12757 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12758 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12759 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12760 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12766 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12768 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12774 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12775 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12777 .
addDef(ActualNegSizeReg)
12779 .
add(
MI.getOperand(2))
12780 .
add(
MI.getOperand(3));
12786 .
addReg(ActualNegSizeReg);
12789 int64_t NegProbeSize = -(int64_t)ProbeSize;
12790 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
12791 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12792 if (!isInt<16>(NegProbeSize)) {
12793 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12795 .
addImm(NegProbeSize >> 16);
12799 .
addImm(NegProbeSize & 0xFFFF);
12806 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12808 .
addReg(ActualNegSizeReg)
12810 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12814 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12817 .
addReg(ActualNegSizeReg);
12826 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12827 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12841 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12852 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12854 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12855 MaxCallFrameSizeReg)
12856 .
add(
MI.getOperand(2))
12857 .
add(
MI.getOperand(3));
12858 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12860 .
addReg(MaxCallFrameSizeReg);
12869 MI.eraseFromParent();
12871 ++NumDynamicAllocaProbed;
12876 switch (
MI.getOpcode()) {
12877 case PPC::SELECT_CC_I4:
12878 case PPC::SELECT_CC_I8:
12879 case PPC::SELECT_CC_F4:
12880 case PPC::SELECT_CC_F8:
12881 case PPC::SELECT_CC_F16:
12882 case PPC::SELECT_CC_VRRC:
12883 case PPC::SELECT_CC_VSFRC:
12884 case PPC::SELECT_CC_VSSRC:
12885 case PPC::SELECT_CC_VSRC:
12886 case PPC::SELECT_CC_SPE4:
12887 case PPC::SELECT_CC_SPE:
12895 switch (
MI.getOpcode()) {
12896 case PPC::SELECT_I4:
12897 case PPC::SELECT_I8:
12898 case PPC::SELECT_F4:
12899 case PPC::SELECT_F8:
12900 case PPC::SELECT_F16:
12901 case PPC::SELECT_SPE:
12902 case PPC::SELECT_SPE4:
12903 case PPC::SELECT_VRRC:
12904 case PPC::SELECT_VSFRC:
12905 case PPC::SELECT_VSSRC:
12906 case PPC::SELECT_VSRC:
12916 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12917 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12919 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12932 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12933 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12935 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12936 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12950 if (Subtarget.hasISEL() &&
12951 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12952 MI.getOpcode() == PPC::SELECT_CC_I8 ||
12953 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
12955 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12956 MI.getOpcode() == PPC::SELECT_CC_I8)
12957 Cond.push_back(
MI.getOperand(4));
12960 Cond.push_back(
MI.getOperand(1));
12963 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12964 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12980 F->insert(It, copy0MBB);
12981 F->insert(It, sinkMBB);
12985 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13000 .
addReg(
MI.getOperand(1).getReg())
13003 unsigned SelectPred =
MI.getOperand(4).getImm();
13006 .
addReg(
MI.getOperand(1).getReg())
13023 .
addReg(
MI.getOperand(3).getReg())
13025 .
addReg(
MI.getOperand(2).getReg())
13027 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13043 F->insert(It, readMBB);
13044 F->insert(It, sinkMBB);
13065 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13075 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13077 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13079 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13081 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13084 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13086 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13088 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13090 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13093 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13095 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13097 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13099 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13102 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13104 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13106 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13108 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13111 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13113 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13115 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13117 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13120 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13122 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13124 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13126 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13129 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13131 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13133 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13135 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13138 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13140 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13142 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13144 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13147 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13149 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13151 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13153 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13156 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13158 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13160 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13162 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13165 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13167 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13169 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13171 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13173 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13174 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13175 (Subtarget.hasPartwordAtomics() &&
13176 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13177 (Subtarget.hasPartwordAtomics() &&
13178 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13179 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13181 auto LoadMnemonic = PPC::LDARX;
13182 auto StoreMnemonic = PPC::STDCX;
13183 switch (
MI.getOpcode()) {
13186 case PPC::ATOMIC_CMP_SWAP_I8:
13187 LoadMnemonic = PPC::LBARX;
13188 StoreMnemonic = PPC::STBCX;
13189 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13191 case PPC::ATOMIC_CMP_SWAP_I16:
13192 LoadMnemonic = PPC::LHARX;
13193 StoreMnemonic = PPC::STHCX;
13194 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13196 case PPC::ATOMIC_CMP_SWAP_I32:
13197 LoadMnemonic = PPC::LWARX;
13198 StoreMnemonic = PPC::STWCX;
13200 case PPC::ATOMIC_CMP_SWAP_I64:
13201 LoadMnemonic = PPC::LDARX;
13202 StoreMnemonic = PPC::STDCX;
13210 Register oldval =
MI.getOperand(3).getReg();
13211 Register newval =
MI.getOperand(4).getReg();
13217 F->insert(It, loop1MBB);
13218 F->insert(It, loop2MBB);
13219 F->insert(It, exitMBB);
13240 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13266 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13267 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13271 bool is64bit = Subtarget.
isPPC64();
13273 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13278 Register oldval =
MI.getOperand(3).getReg();
13279 Register newval =
MI.getOperand(4).getReg();
13285 F->insert(It, loop1MBB);
13286 F->insert(It, loop2MBB);
13287 F->insert(It, exitMBB);
13294 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13313 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13345 if (ptrA != ZeroReg) {
13347 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13356 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13357 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13360 .
addImm(is8bit ? 28 : 27);
13361 if (!isLittleEndian)
13362 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13364 .
addImm(is8bit ? 24 : 16);
13366 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13371 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13376 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13379 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13386 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13390 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13393 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13396 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13401 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13418 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13442 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13467 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13475 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13476 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13477 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13478 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13479 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13480 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13483 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13484 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13488 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13492 .
addReg(
MI.getOperand(1).getReg())
13495 MI.getOperand(0).getReg())
13496 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13497 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13503 MI.getOperand(0).getReg())
13505 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13507 unsigned Imm =
MI.getOperand(1).getImm();
13510 MI.getOperand(0).getReg())
13512 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13514 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13517 if (
MRI.use_empty(OldFPSCRReg))
13518 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13520 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13531 unsigned Mode =
MI.getOperand(1).getImm();
13532 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13536 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13539 }
else if (
MI.getOpcode() == PPC::SETRND) {
13547 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13548 if (Subtarget.hasDirectMove()) {
13549 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13553 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13556 if (RC == &PPC::F8RCRegClass) {
13559 "Unsupported RegClass.");
13561 StoreOp = PPC::STFD;
13566 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13567 "Unsupported RegClass.");
13600 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13603 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13617 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13625 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13626 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13632 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13639 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13648 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13652 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13653 if (
MRI.use_empty(OldFPSCRReg))
13654 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13656 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13659 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13665 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13666 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13668 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13675 .
addUse(Src, 0, PPC::sub_gp8_x1);
13678 .
addUse(Src, 0, PPC::sub_gp8_x0);
13679 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13680 MI.getOpcode() == PPC::STQX_PSEUDO) {
13686 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13692 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13693 :
TII->get(PPC::STQ))
13701 MI.eraseFromParent();
13714 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13717 return RefinementSteps;
13723 EVT VT =
Op.getValueType();
13726 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13750PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13753 EVT VT =
Op.getValueType();
13754 if (VT != MVT::f64 &&
13755 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13762 int Enabled,
int &RefinementSteps,
13763 bool &UseOneConstNR,
13764 bool Reciprocal)
const {
13766 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13767 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13768 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13769 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13775 UseOneConstNR = !Subtarget.needsTwoConstNR();
13783 int &RefinementSteps)
const {
13785 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13786 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13787 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13788 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13796unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13834 unsigned Bytes,
int Dist,
13844 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13845 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13848 if (FS != BFS || FS != (
int)Bytes)
return false;
13852 SDValue Base1 = Loc, Base2 = BaseLoc;
13853 int64_t Offset1 = 0, Offset2 = 0;
13856 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13866 if (isGA1 && isGA2 && GV1 == GV2)
13867 return Offset1 == (Offset2 + Dist*Bytes);
13874 unsigned Bytes,
int Dist,
13877 EVT VT = LS->getMemoryVT();
13878 SDValue Loc = LS->getBasePtr();
13884 switch (
N->getConstantOperandVal(1)) {
13885 default:
return false;
13886 case Intrinsic::ppc_altivec_lvx:
13887 case Intrinsic::ppc_altivec_lvxl:
13888 case Intrinsic::ppc_vsx_lxvw4x:
13889 case Intrinsic::ppc_vsx_lxvw4x_be:
13892 case Intrinsic::ppc_vsx_lxvd2x:
13893 case Intrinsic::ppc_vsx_lxvd2x_be:
13896 case Intrinsic::ppc_altivec_lvebx:
13899 case Intrinsic::ppc_altivec_lvehx:
13902 case Intrinsic::ppc_altivec_lvewx:
13912 switch (
N->getConstantOperandVal(1)) {
13913 default:
return false;
13914 case Intrinsic::ppc_altivec_stvx:
13915 case Intrinsic::ppc_altivec_stvxl:
13916 case Intrinsic::ppc_vsx_stxvw4x:
13919 case Intrinsic::ppc_vsx_stxvd2x:
13922 case Intrinsic::ppc_vsx_stxvw4x_be:
13925 case Intrinsic::ppc_vsx_stxvd2x_be:
13928 case Intrinsic::ppc_altivec_stvebx:
13931 case Intrinsic::ppc_altivec_stvehx:
13934 case Intrinsic::ppc_altivec_stvewx:
13951 SDValue Chain = LD->getChain();
13952 EVT VT = LD->getMemoryVT();
13961 while (!Queue.empty()) {
13962 SDNode *ChainNext = Queue.pop_back_val();
13963 if (!Visited.
insert(ChainNext).second)
13966 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
13970 if (!Visited.
count(ChainLD->getChain().getNode()))
13971 Queue.push_back(ChainLD->getChain().getNode());
13973 for (
const SDUse &O : ChainNext->
ops())
13974 if (!Visited.
count(O.getNode()))
13975 Queue.push_back(O.getNode());
13977 LoadRoots.
insert(ChainNext);
13988 for (
SDNode *
I : LoadRoots) {
13989 Queue.push_back(
I);
13991 while (!Queue.empty()) {
13992 SDNode *LoadRoot = Queue.pop_back_val();
13993 if (!Visited.
insert(LoadRoot).second)
13996 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
14001 if (((isa<MemSDNode>(U) &&
14002 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
14005 Queue.push_back(U);
14038 auto Final = Shifted;
14049 DAGCombinerInfo &DCI)
const {
14057 if (!DCI.isAfterLegalizeDAG())
14062 for (
const SDNode *U :
N->uses())
14067 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14071 if (OpSize <
Size) {
14089 DAGCombinerInfo &DCI)
const {
14093 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14104 N->getValueType(0) != MVT::i1)
14107 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14108 N->getOperand(0).getValueType() != MVT::i64)
14116 cast<CondCodeSDNode>(
N->getOperand(
14118 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14129 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14152 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14153 N->getOperand(0).getOpcode() !=
ISD::OR &&
14154 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14164 N->getOperand(1).getOpcode() !=
ISD::AND &&
14165 N->getOperand(1).getOpcode() !=
ISD::OR &&
14166 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14179 for (
unsigned i = 0; i < 2; ++i) {
14183 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14184 isa<ConstantSDNode>(
N->getOperand(i)))
14195 while (!BinOps.
empty()) {
14203 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14237 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14238 if (isa<ConstantSDNode>(Inputs[i]))
14261 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14283 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14286 if (isa<ConstantSDNode>(Inputs[i]))
14292 std::list<HandleSDNode> PromOpHandles;
14293 for (
auto &PromOp : PromOps)
14294 PromOpHandles.emplace_back(PromOp);
14301 while (!PromOpHandles.empty()) {
14303 PromOpHandles.pop_back();
14309 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14312 PromOpHandles.emplace_front(PromOp);
14317 if (isa<ConstantSDNode>(RepValue))
14326 default:
C = 0;
break;
14331 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14339 PromOpHandles.emplace_front(PromOp);
14347 for (
unsigned i = 0; i < 2; ++i)
14348 if (isa<ConstantSDNode>(Ops[
C+i]))
14357 return N->getOperand(0);
14365 DAGCombinerInfo &DCI)
const {
14383 if (
N->getValueType(0) != MVT::i32 &&
14384 N->getValueType(0) != MVT::i64)
14387 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14388 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14391 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14392 N->getOperand(0).getOpcode() !=
ISD::OR &&
14393 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14404 while (!BinOps.
empty()) {
14412 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14443 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14444 if (isa<ConstantSDNode>(Inputs[i]))
14455 SelectTruncOp[0].
insert(std::make_pair(
User,
14459 SelectTruncOp[0].
insert(std::make_pair(
User,
14462 SelectTruncOp[1].
insert(std::make_pair(
User,
14468 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14477 SelectTruncOp[0].
insert(std::make_pair(
User,
14481 SelectTruncOp[0].
insert(std::make_pair(
User,
14484 SelectTruncOp[1].
insert(std::make_pair(
User,
14490 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14491 bool ReallyNeedsExt =
false;
14495 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14496 if (isa<ConstantSDNode>(Inputs[i]))
14500 Inputs[i].getOperand(0).getValueSizeInBits();
14501 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14506 OpBits-PromBits))) ||
14509 (OpBits-(PromBits-1)))) {
14510 ReallyNeedsExt =
true;
14518 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14522 if (isa<ConstantSDNode>(Inputs[i]))
14525 SDValue InSrc = Inputs[i].getOperand(0);
14539 std::list<HandleSDNode> PromOpHandles;
14540 for (
auto &PromOp : PromOps)
14541 PromOpHandles.emplace_back(PromOp);
14547 while (!PromOpHandles.empty()) {
14549 PromOpHandles.pop_back();
14553 default:
C = 0;
break;
14558 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14566 PromOpHandles.emplace_front(PromOp);
14576 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14578 PromOpHandles.emplace_front(PromOp);
14587 for (
unsigned i = 0; i < 2; ++i) {
14588 if (!isa<ConstantSDNode>(Ops[
C+i]))
14605 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14606 if (SI0 != SelectTruncOp[0].
end())
14608 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14609 if (SI1 != SelectTruncOp[1].
end())
14618 if (!ReallyNeedsExt)
14619 return N->getOperand(0);
14626 N->getValueSizeInBits(0), PromBits),
14627 dl,
N->getValueType(0)));
14630 "Invalid extension type");
14633 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14641 DAGCombinerInfo &DCI)
const {
14643 "Should be called with a SETCC node");
14661 EVT VT =
N->getValueType(0);
14662 EVT OpVT =
LHS.getValueType();
14668 return DAGCombineTruncBoolExt(
N, DCI);
14673 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14675 Op.getValueType() == MVT::f64;
14687combineElementTruncationToVectorTruncation(
SDNode *
N,
14688 DAGCombinerInfo &DCI)
const {
14690 "Should be called with a BUILD_VECTOR node");
14695 SDValue FirstInput =
N->getOperand(0);
14697 "The input operand must be an fp-to-int conversion.");
14706 bool IsSplat =
true;
14711 EVT TargetVT =
N->getValueType(0);
14712 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14713 SDValue NextOp =
N->getOperand(i);
14717 if (NextConversion != FirstConversion)
14725 if (
N->getOperand(i) != FirstInput)
14736 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14737 SDValue In =
N->getOperand(i).getOperand(0);
14760 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14762 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14775 "Should be called with a BUILD_VECTOR node");
14780 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14783 bool InputsAreConsecutiveLoads =
true;
14784 bool InputsAreReverseConsecutive =
true;
14785 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14786 SDValue FirstInput =
N->getOperand(0);
14787 bool IsRoundOfExtLoad =
false;
14792 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
14797 N->getNumOperands() == 1)
14800 if (!IsRoundOfExtLoad)
14801 FirstLoad = cast<LoadSDNode>(FirstInput);
14805 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14807 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14810 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14816 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14817 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
14818 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
14827 InputsAreConsecutiveLoads =
false;
14829 InputsAreReverseConsecutive =
false;
14832 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14837 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14838 "The loads cannot be both consecutive and reverse consecutive.");
14842 if (InputsAreConsecutiveLoads) {
14843 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14847 ReturnSDVal = WideLoad;
14848 }
else if (InputsAreReverseConsecutive) {
14850 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14855 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14859 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14863 for (
auto *LD : InputLoads)
14865 return ReturnSDVal;
14882 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14884 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14886 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14887 CorrectElems = CorrectElems >> 8;
14888 Elems = Elems >> 8;
14895 EVT VT =
N->getValueType(0);
14933 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14953 if (Input && Input != Extract.
getOperand(0))
14959 Elems = Elems << 8;
14968 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14969 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14976 int TgtElemArrayIdx;
14978 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14979 if (InputSize + OutputSize == 40)
14980 TgtElemArrayIdx = 0;
14981 else if (InputSize + OutputSize == 72)
14982 TgtElemArrayIdx = 1;
14983 else if (InputSize + OutputSize == 48)
14984 TgtElemArrayIdx = 2;
14985 else if (InputSize + OutputSize == 80)
14986 TgtElemArrayIdx = 3;
14987 else if (InputSize + OutputSize == 96)
14988 TgtElemArrayIdx = 4;
14992 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14994 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14995 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14996 if (Elems != CorrectElems) {
15012 if (
N->getValueType(0) != MVT::v1i128)
15015 SDValue Operand =
N->getOperand(0);
15021 auto *LD = cast<LoadSDNode>(Operand);
15022 EVT MemoryType = LD->getMemoryVT();
15026 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15027 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15030 if (!ValidLDType ||
15036 LD->getChain(), LD->getBasePtr(),
15040 DAG.
getVTList(MVT::v1i128, MVT::Other),
15041 LoadOps, MemoryType, LD->getMemOperand());
15045 DAGCombinerInfo &DCI)
const {
15047 "Should be called with a BUILD_VECTOR node");
15052 if (!Subtarget.hasVSX())
15058 SDValue FirstInput =
N->getOperand(0);
15060 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15075 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15084 if (Subtarget.isISA3_1()) {
15090 if (
N->getValueType(0) != MVT::v2f64)
15101 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15105 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15112 if (!Ext1Op || !Ext2Op)
15121 if (FirstElem == 0 && SecondElem == 1)
15123 else if (FirstElem == 2 && SecondElem == 3)
15131 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15136 DAGCombinerInfo &DCI)
const {
15139 "Need an int -> FP conversion node here");
15150 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15152 if (!
Op.getOperand(0).getValueType().isSimple())
15154 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15155 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15158 SDValue FirstOperand(
Op.getOperand(0));
15159 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15160 (FirstOperand.getValueType() == MVT::i8 ||
15161 FirstOperand.getValueType() == MVT::i16);
15162 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15164 bool DstDouble =
Op.getValueType() == MVT::f64;
15165 unsigned ConvOp =
Signed ?
15171 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15180 SDValue ExtOps[] = { Ld, WidthConst };
15182 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15184 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15192 if (
Op.getOperand(0).getValueType() == MVT::i32)
15196 "UINT_TO_FP is supported only with FPCVT");
15200 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15205 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15212 Subtarget.hasFPCVT()) ||
15214 SDValue Src =
Op.getOperand(0).getOperand(0);
15215 if (Src.getValueType() == MVT::f32) {
15217 DCI.AddToWorklist(Src.getNode());
15218 }
else if (Src.getValueType() != MVT::f64) {
15230 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15233 DCI.AddToWorklist(
FP.getNode());
15257 switch (
N->getOpcode()) {
15262 Chain = LD->getChain();
15263 Base = LD->getBasePtr();
15264 MMO = LD->getMemOperand();
15283 MVT VecTy =
N->getValueType(0).getSimpleVT();
15291 Chain = Load.getValue(1);
15297 if (VecTy != MVT::v2f64) {
15324 switch (
N->getOpcode()) {
15329 Chain = ST->getChain();
15330 Base = ST->getBasePtr();
15331 MMO = ST->getMemOperand();
15351 SDValue Src =
N->getOperand(SrcOpnd);
15352 MVT VecTy = Src.getValueType().getSimpleVT();
15355 if (VecTy != MVT::v2f64) {
15361 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15367 StoreOps, VecTy, MMO);
15374 DAGCombinerInfo &DCI)
const {
15377 unsigned Opcode =
N->getOperand(1).getOpcode();
15379 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15383 &&
"Not a FP_TO_INT Instruction!");
15385 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15386 EVT Op1VT =
N->getOperand(1).getValueType();
15389 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15393 bool ValidTypeForStoreFltAsInt =
15394 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15395 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15398 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15401 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15402 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15409 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15415 cast<StoreSDNode>(
N)->getMemoryVT(),
15416 cast<StoreSDNode>(
N)->getMemOperand());
15424 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15425 for (
int i = 1, e = Mask.size(); i < e; i++) {
15426 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15428 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15430 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15442 FirstOp =
Op.getOperand(i);
15449 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15459 Op =
Op.getOperand(0);
15474 int LHSMaxIdx,
int RHSMinIdx,
15475 int RHSMaxIdx,
int HalfVec,
15476 unsigned ValidLaneWidth,
15478 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15479 int Idx = ShuffV[i];
15480 if ((
Idx >= 0 &&
Idx < LHSMaxIdx) || (
Idx >= RHSMinIdx &&
Idx < RHSMaxIdx))
15482 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15493 SDLoc dl(OrigSToV);
15496 "Expecting a SCALAR_TO_VECTOR here");
15509 "Cannot produce a permuted scalar_to_vector for one element vector");
15511 unsigned ResultInElt = NumElts / 2;
15513 NewMask[ResultInElt] =
Idx->getZExtValue();
15538 int NumElts =
LHS.getValueType().getVectorNumElements();
15548 if (!Subtarget.hasDirectMove())
15558 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15567 if (SToVLHS || SToVRHS) {
15574 if (SToVLHS && SToVRHS &&
15581 int NumEltsOut = ShuffV.
size();
15586 unsigned ValidLaneWidth =
15588 LHS.getValueType().getScalarSizeInBits()
15590 RHS.getValueType().getScalarSizeInBits();
15594 int LHSMaxIdx = -1;
15595 int RHSMinIdx = -1;
15596 int RHSMaxIdx = -1;
15597 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
15609 LHSMaxIdx = NumEltsOut / NumEltsIn;
15618 RHSMinIdx = NumEltsOut;
15619 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15632 HalfVec, ValidLaneWidth, Subtarget);
15637 if (!isa<ShuffleVectorSDNode>(Res))
15639 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15658 if (IsLittleEndian) {
15661 if (Mask[0] < NumElts)
15662 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15666 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15671 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15675 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15680 if (Mask[0] < NumElts)
15681 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15685 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15690 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
15694 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15701 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
15704 if (IsLittleEndian)
15713 DAGCombinerInfo &DCI)
const {
15715 "Not a reverse memop pattern!");
15720 auto I =
Mask.rbegin();
15721 auto E =
Mask.rend();
15723 for (;
I != E; ++
I) {
15740 if (!Subtarget.hasP9Vector())
15743 if(!IsElementReverse(SVN))
15782 if (IntrinsicID == Intrinsic::ppc_stdcx)
15784 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15786 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15788 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15799 switch (
N->getOpcode()) {
15802 return combineADD(
N, DCI);
15811 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
15821 if (!isUInt<32>(Imm))
15828 return combineSHL(
N, DCI);
15830 return combineSRA(
N, DCI);
15832 return combineSRL(
N, DCI);
15834 return combineMUL(
N, DCI);
15837 return combineFMALike(
N, DCI);
15840 return N->getOperand(0);
15844 return N->getOperand(0);
15850 return N->getOperand(0);
15856 return DAGCombineExtBoolTrunc(
N, DCI);
15858 return combineTRUNCATE(
N, DCI);
15860 if (
SDValue CSCC = combineSetCC(
N, DCI))
15864 return DAGCombineTruncBoolExt(
N, DCI);
15867 return combineFPToIntToFP(
N, DCI);
15870 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15871 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15873 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15876 EVT Op1VT =
N->getOperand(1).getValueType();
15877 unsigned Opcode =
N->getOperand(1).getOpcode();
15881 SDValue Val = combineStoreFPToInt(
N, DCI);
15888 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15894 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15895 N->getOperand(1).getNode()->hasOneUse() &&
15896 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15897 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15901 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15905 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15912 if (Op1VT.
bitsGT(mVT)) {
15917 if (Op1VT == MVT::i64)
15922 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15926 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15927 cast<StoreSDNode>(
N)->getMemOperand());
15933 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
15935 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15945 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15954 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15955 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
15962 EVT VT = LD->getValueType(0);
15969 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
15970 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
15981 auto ReplaceTwoFloatLoad = [&]() {
15982 if (VT != MVT::i64)
15997 if (!LD->hasNUsesOfValue(2, 0))
16000 auto UI = LD->use_begin();
16001 while (UI.getUse().getResNo() != 0) ++UI;
16003 while (UI.getUse().getResNo() != 0) ++UI;
16004 SDNode *RightShift = *UI;
16012 if (RightShift->getOpcode() !=
ISD::SRL ||
16013 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
16014 RightShift->getConstantOperandVal(1) != 32 ||
16015 !RightShift->hasOneUse())
16018 SDNode *Trunc2 = *RightShift->use_begin();
16028 Bitcast->getValueType(0) != MVT::f32)
16040 SDValue BasePtr = LD->getBasePtr();
16041 if (LD->isIndexed()) {
16043 "Non-pre-inc AM on PPC?");
16051 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16052 LD->getPointerInfo(), LD->getAlign(),
16053 MMOFlags, LD->getAAInfo());
16059 LD->getPointerInfo().getWithOffset(4),
16062 if (LD->isIndexed()) {
16076 if (ReplaceTwoFloatLoad())
16079 EVT MemVT = LD->getMemoryVT();
16082 if (LD->isUnindexed() && VT.
isVector() &&
16085 !Subtarget.hasP8Vector() &&
16086 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16087 VT == MVT::v4f32))) &&
16088 LD->getAlign() < ABIAlignment) {
16090 SDValue Chain = LD->getChain();
16119 MVT PermCntlTy, PermTy, LDTy;
16120 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16121 : Intrinsic::ppc_altivec_lvsl;
16122 IntrLD = Intrinsic::ppc_altivec_lvx;
16123 IntrPerm = Intrinsic::ppc_altivec_vperm;
16124 PermCntlTy = MVT::v16i8;
16125 PermTy = MVT::v4i32;
16144 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16148 BaseLoadOps, LDTy, BaseMMO);
16157 int IncValue = IncOffset;
16174 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16178 ExtraLoadOps, LDTy, ExtraMMO);
16189 if (isLittleEndian)
16191 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16194 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16197 Perm = Subtarget.hasAltivec()
16213 unsigned IID =
N->getConstantOperandVal(0);
16215 : Intrinsic::ppc_altivec_lvsl);
16216 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16223 .
zext(
Add.getScalarValueSizeInBits()))) {
16224 SDNode *BasePtr =
Add->getOperand(0).getNode();
16225 for (
SDNode *U : BasePtr->uses()) {
16227 U->getConstantOperandVal(0) == IID) {
16237 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16238 SDNode *BasePtr =
Add->getOperand(0).getNode();
16239 for (
SDNode *U : BasePtr->uses()) {
16241 isa<ConstantSDNode>(U->getOperand(1)) &&
16242 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16248 V->getConstantOperandVal(0) == IID) {
16260 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16261 IID == Intrinsic::ppc_altivec_vmaxsh ||
16262 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16278 V2.getOperand(1) == V1) {
16293 switch (
N->getConstantOperandVal(1)) {
16296 case Intrinsic::ppc_altivec_vsum4sbs:
16297 case Intrinsic::ppc_altivec_vsum4shs:
16298 case Intrinsic::ppc_altivec_vsum4ubs: {
16304 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16305 APInt APSplatBits, APSplatUndef;
16306 unsigned SplatBitSize;
16309 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16312 if (BVNIsConstantSplat && APSplatBits == 0)
16317 case Intrinsic::ppc_vsx_lxvw4x:
16318 case Intrinsic::ppc_vsx_lxvd2x:
16330 switch (
N->getConstantOperandVal(1)) {
16333 case Intrinsic::ppc_vsx_stxvw4x:
16334 case Intrinsic::ppc_vsx_stxvd2x:
16343 bool Is64BitBswapOn64BitTgt =
16344 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16346 N->getOperand(0).hasOneUse();
16347 if (IsSingleUseNormalLd &&
16348 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16349 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16360 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16361 MVT::i64 : MVT::i32, MVT::Other),
16362 Ops, LD->getMemoryVT(), LD->getMemOperand());
16366 if (
N->getValueType(0) == MVT::i16)
16383 !IsSingleUseNormalLd)
16385 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16388 if (!LD->isSimple())
16390 SDValue BasePtr = LD->getBasePtr();
16392 LD->getPointerInfo(), LD->getAlign());
16397 LD->getMemOperand(), 4, 4);
16407 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16416 if (!
N->getOperand(0).hasOneUse() &&
16417 !
N->getOperand(1).hasOneUse() &&
16418 !
N->getOperand(2).hasOneUse()) {
16421 SDNode *VCMPrecNode =
nullptr;
16423 SDNode *LHSN =
N->getOperand(0).getNode();
16427 UI->getOperand(1) ==
N->getOperand(1) &&
16428 UI->getOperand(2) ==
N->getOperand(2) &&
16429 UI->getOperand(0) ==
N->getOperand(0)) {
16442 SDNode *FlagUser =
nullptr;
16444 FlagUser ==
nullptr; ++UI) {
16445 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16458 return SDValue(VCMPrecNode, 0);
16480 auto RHSAPInt =
RHS->getAsAPIntVal();
16481 if (!RHSAPInt.isIntN(64))
16484 unsigned Val = RHSAPInt.getZExtValue();
16485 auto isImpossibleCompare = [&]() {
16488 if (Val != 0 && Val != 1) {
16490 return N->getOperand(0);
16493 N->getOperand(0),
N->getOperand(4));
16498 unsigned StoreWidth = 0;
16501 if (
SDValue Impossible = isImpossibleCompare())
16515 auto *MemNode = cast<MemSDNode>(
LHS);
16518 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16519 MemNode->getMemoryVT(), MemNode->getMemOperand());
16523 if (
N->getOperand(0) ==
LHS.getValue(1))
16524 InChain =
LHS.getOperand(0);
16536 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16542 assert(isDot &&
"Can't compare against a vector result!");
16544 if (
SDValue Impossible = isImpossibleCompare())
16547 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16554 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16559 switch (
LHS.getConstantOperandVal(1)) {
16578 N->getOperand(4), CompNode.
getValue(1));
16583 return DAGCombineBuildVector(
N, DCI);
16594 EVT VT =
N->getValueType(0);
16595 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16597 if ((VT != MVT::i32 && VT != MVT::i64) ||
16605 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16625 const APInt &DemandedElts,
16627 unsigned Depth)
const {
16629 switch (
Op.getOpcode()) {
16633 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16634 Known.
Zero = 0xFFFF0000;
16638 switch (
Op.getConstantOperandVal(0)) {
16640 case Intrinsic::ppc_altivec_vcmpbfp_p:
16641 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16642 case Intrinsic::ppc_altivec_vcmpequb_p:
16643 case Intrinsic::ppc_altivec_vcmpequh_p:
16644 case Intrinsic::ppc_altivec_vcmpequw_p:
16645 case Intrinsic::ppc_altivec_vcmpequd_p:
16646 case Intrinsic::ppc_altivec_vcmpequq_p:
16647 case Intrinsic::ppc_altivec_vcmpgefp_p:
16648 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16649 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16650 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16651 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16652 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16653 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16654 case Intrinsic::ppc_altivec_vcmpgtub_p:
16655 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16656 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16657 case Intrinsic::ppc_altivec_vcmpgtud_p:
16658 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16665 switch (
Op.getConstantOperandVal(1)) {
16668 case Intrinsic::ppc_load2r:
16670 Known.
Zero = 0xFFFF0000;
16701 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16710 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16712 LoopSize +=
TII->getInstSizeInBytes(J);
16717 if (LoopSize > 16 && LoopSize <= 32)
16731 if (Constraint.
size() == 1) {
16732 switch (Constraint[0]) {
16750 }
else if (Constraint ==
"wc") {
16752 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16753 Constraint ==
"wf" || Constraint ==
"ws" ||
16754 Constraint ==
"wi" || Constraint ==
"ww") {
16767 Value *CallOperandVal =
info.CallOperandVal;
16770 if (!CallOperandVal)
16777 else if ((
StringRef(constraint) ==
"wa" ||
16789 switch (*constraint) {
16819std::pair<unsigned, const TargetRegisterClass *>
16823 if (Constraint.
size() == 1) {
16825 switch (Constraint[0]) {
16827 if (VT == MVT::i64 && Subtarget.
isPPC64())
16828 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16829 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16831 if (VT == MVT::i64 && Subtarget.
isPPC64())
16832 return std::make_pair(0U, &PPC::G8RCRegClass);
16833 return std::make_pair(0U, &PPC::GPRCRegClass);
16839 if (Subtarget.hasSPE()) {
16840 if (VT == MVT::f32 || VT == MVT::i32)
16841 return std::make_pair(0U, &PPC::GPRCRegClass);
16842 if (VT == MVT::f64 || VT == MVT::i64)
16843 return std::make_pair(0U, &PPC::SPERCRegClass);
16845 if (VT == MVT::f32 || VT == MVT::i32)
16846 return std::make_pair(0U, &PPC::F4RCRegClass);
16847 if (VT == MVT::f64 || VT == MVT::i64)
16848 return std::make_pair(0U, &PPC::F8RCRegClass);
16852 if (Subtarget.hasAltivec() && VT.
isVector())
16853 return std::make_pair(0U, &PPC::VRRCRegClass);
16854 else if (Subtarget.hasVSX())
16856 return std::make_pair(0U, &PPC::VFRCRegClass);
16859 return std::make_pair(0U, &PPC::CRRCRegClass);
16861 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16863 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16864 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16865 Constraint ==
"wf" || Constraint ==
"wi") &&
16866 Subtarget.hasVSX()) {
16870 return std::make_pair(0U, &PPC::VSRCRegClass);
16871 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16872 return std::make_pair(0U, &PPC::VSSRCRegClass);
16873 return std::make_pair(0U, &PPC::VSFRCRegClass);
16874 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16875 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16876 return std::make_pair(0U, &PPC::VSSRCRegClass);
16878 return std::make_pair(0U, &PPC::VSFRCRegClass);
16879 }
else if (Constraint ==
"lr") {
16880 if (VT == MVT::i64)
16881 return std::make_pair(0U, &PPC::LR8RCRegClass);
16883 return std::make_pair(0U, &PPC::LRRCRegClass);
16888 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16892 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16893 int VSNum = atoi(Constraint.
data() + 3);
16894 assert(VSNum >= 0 && VSNum <= 63 &&
16895 "Attempted to access a vsr out of range");
16897 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16898 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16903 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16904 int RegNum = atoi(Constraint.
data() + 2);
16905 if (RegNum > 31 || RegNum < 0)
16907 if (VT == MVT::f32 || VT == MVT::i32)
16908 return Subtarget.hasSPE()
16909 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16910 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16911 if (VT == MVT::f64 || VT == MVT::i64)
16912 return Subtarget.hasSPE()
16913 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16914 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16918 std::pair<unsigned, const TargetRegisterClass *> R =
16927 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16928 PPC::GPRCRegClass.contains(R.first))
16929 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16930 PPC::sub_32, &PPC::G8RCRegClass),
16931 &PPC::G8RCRegClass);
16934 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16935 R.first = PPC::CR0;
16936 R.second = &PPC::CRRCRegClass;
16940 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16941 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16942 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16943 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16944 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16945 "default AIX AltiVec ABI and cannot be used\n";
16955 std::vector<SDValue> &Ops,
16960 if (Constraint.
size() > 1)
16963 char Letter = Constraint[0];
16978 EVT TCVT = MVT::i64;
16983 if (isInt<16>(
Value))
16987 if (isShiftedUInt<16, 16>(
Value))
16991 if (isShiftedInt<16, 16>(
Value))
16995 if (isUInt<16>(
Value))
17011 if (isInt<16>(-
Value))
17019 if (Result.getNode()) {
17020 Ops.push_back(Result);
17031 if (
I.getNumOperands() <= 1)
17033 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17035 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17036 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17037 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17040 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17068 switch (AM.
Scale) {
17099 unsigned Depth =
Op.getConstantOperandVal(0);
17105 bool isPPC64 = Subtarget.
isPPC64();
17117 isPPC64 ? MVT::i64 : MVT::i32);
17124 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17132 unsigned Depth =
Op.getConstantOperandVal(0);
17139 bool isPPC64 = PtrVT == MVT::i64;
17145 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17147 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17161 bool isPPC64 = Subtarget.
isPPC64();
17195 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17213 unsigned Intrinsic)
const {
17214 switch (Intrinsic) {
17215 case Intrinsic::ppc_atomicrmw_xchg_i128:
17216 case Intrinsic::ppc_atomicrmw_add_i128:
17217 case Intrinsic::ppc_atomicrmw_sub_i128:
17218 case Intrinsic::ppc_atomicrmw_nand_i128:
17219 case Intrinsic::ppc_atomicrmw_and_i128:
17220 case Intrinsic::ppc_atomicrmw_or_i128:
17221 case Intrinsic::ppc_atomicrmw_xor_i128:
17222 case Intrinsic::ppc_cmpxchg_i128:
17224 Info.memVT = MVT::i128;
17225 Info.ptrVal =
I.getArgOperand(0);
17231 case Intrinsic::ppc_atomic_load_i128:
17233 Info.memVT = MVT::i128;
17234 Info.ptrVal =
I.getArgOperand(0);
17239 case Intrinsic::ppc_atomic_store_i128:
17241 Info.memVT = MVT::i128;
17242 Info.ptrVal =
I.getArgOperand(2);
17247 case Intrinsic::ppc_altivec_lvx:
17248 case Intrinsic::ppc_altivec_lvxl:
17249 case Intrinsic::ppc_altivec_lvebx:
17250 case Intrinsic::ppc_altivec_lvehx:
17251 case Intrinsic::ppc_altivec_lvewx:
17252 case Intrinsic::ppc_vsx_lxvd2x:
17253 case Intrinsic::ppc_vsx_lxvw4x:
17254 case Intrinsic::ppc_vsx_lxvd2x_be:
17255 case Intrinsic::ppc_vsx_lxvw4x_be:
17256 case Intrinsic::ppc_vsx_lxvl:
17257 case Intrinsic::ppc_vsx_lxvll: {
17259 switch (Intrinsic) {
17260 case Intrinsic::ppc_altivec_lvebx:
17263 case Intrinsic::ppc_altivec_lvehx:
17266 case Intrinsic::ppc_altivec_lvewx:
17269 case Intrinsic::ppc_vsx_lxvd2x:
17270 case Intrinsic::ppc_vsx_lxvd2x_be:
17280 Info.ptrVal =
I.getArgOperand(0);
17287 case Intrinsic::ppc_altivec_stvx:
17288 case Intrinsic::ppc_altivec_stvxl:
17289 case Intrinsic::ppc_altivec_stvebx:
17290 case Intrinsic::ppc_altivec_stvehx:
17291 case Intrinsic::ppc_altivec_stvewx:
17292 case Intrinsic::ppc_vsx_stxvd2x:
17293 case Intrinsic::ppc_vsx_stxvw4x:
17294 case Intrinsic::ppc_vsx_stxvd2x_be:
17295 case Intrinsic::ppc_vsx_stxvw4x_be:
17296 case Intrinsic::ppc_vsx_stxvl:
17297 case Intrinsic::ppc_vsx_stxvll: {
17299 switch (Intrinsic) {
17300 case Intrinsic::ppc_altivec_stvebx:
17303 case Intrinsic::ppc_altivec_stvehx:
17306 case Intrinsic::ppc_altivec_stvewx:
17309 case Intrinsic::ppc_vsx_stxvd2x:
17310 case Intrinsic::ppc_vsx_stxvd2x_be:
17320 Info.ptrVal =
I.getArgOperand(1);
17327 case Intrinsic::ppc_stdcx:
17328 case Intrinsic::ppc_stwcx:
17329 case Intrinsic::ppc_sthcx:
17330 case Intrinsic::ppc_stbcx: {
17332 auto Alignment =
Align(8);
17333 switch (Intrinsic) {
17334 case Intrinsic::ppc_stdcx:
17337 case Intrinsic::ppc_stwcx:
17339 Alignment =
Align(4);
17341 case Intrinsic::ppc_sthcx:
17343 Alignment =
Align(2);
17345 case Intrinsic::ppc_stbcx:
17347 Alignment =
Align(1);
17352 Info.ptrVal =
I.getArgOperand(0);
17354 Info.align = Alignment;
17372 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17373 if (
Op.isMemset() && Subtarget.hasVSX()) {
17378 if (TailSize > 2 && TailSize <= 4) {
17383 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17402 return !(BitSize == 0 || BitSize > 64);
17410 return NumBits1 == 64 && NumBits2 == 32;
17418 return NumBits1 == 64 && NumBits2 == 32;
17424 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17425 EVT MemVT = LD->getMemoryVT();
17426 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17427 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17443 "invalid fpext types");
17445 if (DestVT == MVT::f128)
17451 return isInt<16>(Imm) || isUInt<16>(Imm);
17455 return isInt<16>(Imm) || isUInt<16>(Imm);
17460 unsigned *
Fast)
const {
17474 !Subtarget.allowsUnalignedFPAccess())
17478 if (Subtarget.hasVSX()) {
17479 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17480 VT != MVT::v4f32 && VT != MVT::v4i32)
17487 if (VT == MVT::ppcf128)
17501 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17502 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17510 int64_t Imm = ConstNode->getSExtValue();
17511 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17513 if (isInt<16>(Imm))
17538 return Subtarget.hasP9Vector();
17546 if (!
I->hasOneUse())
17550 assert(
User &&
"A single use instruction with no uses.");
17552 switch (
I->getOpcode()) {
17553 case Instruction::FMul: {
17555 if (
User->getOpcode() != Instruction::FSub &&
17556 User->getOpcode() != Instruction::FAdd)
17569 case Instruction::Load: {
17582 if (
User->getOpcode() != Instruction::Store)
17602 static const MCPhysReg ScratchRegs[] = {
17603 PPC::X12, PPC::LR8, PPC::CTR8, 0
17606 return ScratchRegs;
17610 const Constant *PersonalityFn)
const {
17611 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17615 const Constant *PersonalityFn)
const {
17616 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17621 EVT VT ,
unsigned DefinedValues)
const {
17622 if (VT == MVT::v2i64)
17623 return Subtarget.hasDirectMove();
17625 if (Subtarget.hasVSX())
17659 bool LegalOps,
bool OptForSize,
17661 unsigned Depth)
const {
17665 unsigned Opc =
Op.getOpcode();
17666 EVT VT =
Op.getValueType();
17691 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17695 N0Cost,
Depth + 1);
17699 N1Cost,
Depth + 1);
17701 if (NegN0 && N0Cost <= N1Cost) {
17702 Cost = std::min(N0Cost, N2Cost);
17703 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17704 }
else if (NegN1) {
17705 Cost = std::min(N1Cost, N2Cost);
17706 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17749 bool ForCodeSize)
const {
17750 if (!VT.
isSimple() || !Subtarget.hasVSX())
17760 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
17765 APSInt IntResult(16,
false);
17770 if (IsExact && IntResult <= 15 && IntResult >= -16)
17772 return Imm.isZero();
17775 return Imm.isPosZero();
17787 unsigned Opcode =
N->getOpcode();
17788 unsigned TargetOpcode;
17807 if (Mask->getZExtValue() == OpSizeInBits - 1)
17813SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17819 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17822 N->getValueType(0) != MVT::i64)
17837 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17843SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17850SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17869 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17871 Op.getValueType() != MVT::i64)
17875 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17876 Cmp.getOperand(0).getValueType() != MVT::i64)
17879 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
17880 int64_t NegConstant = 0 -
Constant->getSExtValue();
17883 return isInt<16>(NegConstant);
17889 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
17890 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
17893 if (LHSHasPattern && !RHSHasPattern)
17895 else if (!LHSHasPattern && !RHSHasPattern)
17901 SDValue Z = Cmp.getOperand(0);
17902 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
17903 int64_t NegConstant = 0 -
Constant->getSExtValue();
17905 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
17916 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17931 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17968 if (!GSDN || !ConstNode)
17975 if (!isInt<34>(NewOffset))
17988SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18008 DAGCombinerInfo &DCI)
const {
18010 if (Subtarget.useCRBits()) {
18012 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
18013 return CRTruncValue;
18020 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
18023 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18033 EltToExtract = EltToExtract ? 0 : 1;
18043 return DCI.DAG.getNode(
18045 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18050SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18054 if (!ConstOpOrElement)
18062 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18086 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18090 EVT VT =
N->getValueType(0);
18097 if ((MulAmtAbs - 1).isPowerOf2()) {
18101 if (!IsProfitable(IsNeg,
true, VT))
18114 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18118 if (!IsProfitable(IsNeg,
false, VT))
18139 DAGCombinerInfo &DCI)
const {
18144 EVT VT =
N->getValueType(0);
18147 unsigned Opc =
N->getOpcode();
18149 bool LegalOps = !DCI.isBeforeLegalizeOps();
18157 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18173bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18190 if (!Callee ||
Callee->isVarArg())
18203bool PPCTargetLowering::
18204isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18207 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18209 if (CI->getBitWidth() > 64)
18211 int64_t ConstVal = CI->getZExtValue();
18212 return isUInt<16>(ConstVal) ||
18213 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18222PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18228 if ((Flags & FlagSet) == FlagSet)
18231 if ((Flags & FlagSet) == FlagSet)
18234 if ((Flags & FlagSet) == FlagSet)
18237 if ((Flags & FlagSet) == FlagSet)
18258 if ((FrameIndexAlign % 4) != 0)
18259 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18260 if ((FrameIndexAlign % 16) != 0)
18261 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18265 if ((FrameIndexAlign % 4) == 0)
18267 if ((FrameIndexAlign % 16) == 0)
18280 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18281 if ((Imm & 0x3) == 0)
18283 if ((Imm & 0xf) == 0)
18289 const APInt &ConstImm = CN->getAPIntValue();
18308 const APInt &ConstImm = CN->getAPIntValue();
18318 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18330 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18331 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18332 isValidPCRelNode<JumpTableSDNode>(
N) ||
18333 isValidPCRelNode<BlockAddressSDNode>(
N));
18338unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18343 if (!Subtarget.hasP9Vector())
18348 if (Subtarget.hasPrefixInstrs())
18351 if (Subtarget.hasSPE())
18360 unsigned ParentOp = Parent->
getOpcode();
18364 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18365 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18376 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18377 if (LSB->isIndexed())
18382 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18383 assert(MN &&
"Parent should be a MemSDNode!");
18388 "Not expecting scalar integers larger than 16 bytes!");
18391 else if (
Size == 32)
18398 else if (
Size == 256) {
18399 assert(Subtarget.pairedVectorMemops() &&
18400 "256-bit vectors are only available when paired vector memops is "
18408 else if (MemVT == MVT::f128 || MemVT.
isVector())
18418 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18439 FlagSet &= ~PPC::MOF_NoExt;
18444 bool IsNonP1034BitConst =
18448 IsNonP1034BitConst)
18461 int16_t ForceXFormImm = 0;
18464 Disp =
N.getOperand(0);
18465 Base =
N.getOperand(1);
18476 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18477 Disp =
N.getOperand(0);
18478 Base =
N.getOperand(1);
18492 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18498 if (PartVT == MVT::f64 &&
18499 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18508SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18512 EVT RetVT =
Op.getValueType();
18520 EVT ArgVT =
N.getValueType();
18525 Entry.IsZExt = !Entry.IsSExt;
18526 Args.push_back(Entry);
18534 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18540 .setTailCall(isTailCall)
18547SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18548 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18550 if (
Op.getValueType() == MVT::f32)
18551 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18553 if (
Op.getValueType() == MVT::f64)
18554 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18559bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18561 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18565bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18566 return Op.getNode()->getFlags().hasApproximateFuncs();
18569bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18573SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18574 const char *LibCallFloatName,
18575 const char *LibCallDoubleNameFinite,
18576 const char *LibCallFloatNameFinite,
18579 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18582 if (!isLowringToMASSFiniteSafe(
Op))
18583 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18586 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18587 LibCallDoubleNameFinite,
Op, DAG);
18591 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18592 "__xl_powf_finite",
Op, DAG);
18596 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18597 "__xl_sinf_finite",
Op, DAG);
18601 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18602 "__xl_cosf_finite",
Op, DAG);
18606 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18607 "__xl_logf_finite",
Op, DAG);
18611 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18612 "__xl_log10f_finite",
Op, DAG);
18616 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18617 "__xl_expf_finite",
Op, DAG);
18624 if (!isa<FrameIndexSDNode>(
N))
18642 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18654 "Must be using PC-Relative calls when a valid PC-Relative node is "
18684 Disp =
N.getOperand(1).getOperand(0);
18689 Base =
N.getOperand(0);
18696 auto *CN = cast<ConstantSDNode>(
N);
18697 EVT CNType = CN->getValueType(0);
18698 uint64_t CNImm = CN->getZExtValue();
18709 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
18711 int32_t
Addr = (int32_t)CNImm;
18716 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18732 unsigned Opcode =
N.getOpcode();
18740 Base =
N.getOperand(0);
18759 Base = FI ?
N :
N.getOperand(1);
18771 bool IsVarArg)
const {
18781 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18815 return Intrinsic::ppc_atomicrmw_xchg_i128;
18817 return Intrinsic::ppc_atomicrmw_add_i128;
18819 return Intrinsic::ppc_atomicrmw_sub_i128;
18821 return Intrinsic::ppc_atomicrmw_and_i128;
18823 return Intrinsic::ppc_atomicrmw_or_i128;
18825 return Intrinsic::ppc_atomicrmw_xor_i128;
18827 return Intrinsic::ppc_atomicrmw_nand_i128;
18844 Value *LoHi = Builder.
CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
18850 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
18871 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
18878 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &dl)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live propagate it s liveness to any other values it uses(according to Uses). void DeadArgumentEliminationPass
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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...
This defines the Use class.
static bool isConstantOrUndef(const SDValue Op)
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).
unsigned const TargetRegisterInfo * TRI
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
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 areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static 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 bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
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 void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSMaxIdx, int RHSMinIdx, int RHSMaxIdx, int HalfVec, unsigned ValidLaneWidth, const PPCSubtarget &Subtarget)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
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 const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
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 convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static int getEstimateRefinementSteps(EVT VT, const PPCSubtarget &Subtarget)
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
cl::opt< bool > ANDIGlueBug
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
const char LLVMTargetMachineRef TM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This file describes how to lower LLVM code to machine code.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool is64Bit(const char *name)
bool isFixed(unsigned ValNo) const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
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 isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
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.
An arbitrary precision integer that knows its signedness.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
This is an SDNode representing atomic operations.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
InstListType::const_iterator const_iterator
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
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.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
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.
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
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].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
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.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
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.
BasicBlockListType::const_iterator const_iterator
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
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
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
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.
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.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
BasicBlock * GetInsertBlock() const
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ INVALID_SIMPLE_VALUE_TYPE
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()
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.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
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 '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
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
bool useSoftFloat() const
const PPCFrameLowering * getFrameLowering() const override
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
const PPCInstrInfo * getInstrInfo() const override
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool isLittleEndian() const
bool isTargetLinux() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
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
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &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...
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...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
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.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
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.
uint64_t getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(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
bool useLoadStackGuardNode() const override
Override to support customized stack guard loading.
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
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< 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.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
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.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
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 getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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),...
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
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.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
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.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
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)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getRegister(unsigned Reg, EVT VT)
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...
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 ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
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...
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
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)
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.
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)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
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 getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
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.
SDValue getRegisterMask(const uint32_t *RegMask)
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...
SDValue getCondCode(ISD::CondCode Cond)
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
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=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
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.
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.
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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.
StackOffset holds a fixed and a scalable offset in bytes.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
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...
virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual 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...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
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.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
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
virtual bool useLoadStackGuardNode() const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
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.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
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 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
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.
bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
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 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.
@ 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.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ 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.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ 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.
@ BR_JT
BR_JT - Jumptable branch.
@ 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,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ 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...
@ 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...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ 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.
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.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_PPC_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,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ TLSLD_AIX
[GP|G8]RC = TLSLD_AIX, TOC_ENTRY(module handle) Op that requires a single input of the module handle ...
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ STORE_COND
CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr The store conditional instruction ST[BHWD]ARX that produces a...
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ RET_GLUE
Return with a glue operand, matched by 'blr'.
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec and local-exec TLS models,...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ GET_TLS_MOD_AIX
x3 = GET_TLS_MOD_AIX _$TLSML - For the AIX local-dynamic TLS model, produces a call to ....
@ LD_VSX_LH
VSRC, CHAIN = LD_VSX_LH CHAIN, Ptr - This is a floating-point load of a v2f32 value into the lower ha...
@ PROBED_ALLOCA
To avoid stack clash, allocation is performed by block and each block is probed.
@ XXMFACC
XXMFACC = This corresponds to the xxmfacc instruction.
@ ADDIS_TLSGD_HA
G8RC = ADDIS_TLSGD_HA x2, Symbol - For the general-dynamic TLS model, produces an ADDIS8 instruction ...
@ ACC_BUILD
ACC_BUILD = Build an accumulator register from 4 VSX registers.
@ GlobalBaseReg
The result of the mflr at function entry, used for PIC code.
@ LXVD2X
VSRC, CHAIN = LXVD2X_LE CHAIN, Ptr - Occurs only for little endian.
@ XSMAXC
XSMAXC[DQ]P, XSMINC[DQ]P - C-type min/max instructions.
@ CALL
CALL - A direct function call.
@ MTCTR
CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a MTCTR instruction.
@ TC_RETURN
TC_RETURN - A tail call return.
@ STFIWX
STFIWX - The STFIWX instruction.
@ LD_SPLAT
VSRC, CHAIN = LD_SPLAT, CHAIN, Ptr - a splatting load memory instructions such as LXVDSX,...
@ VCMP_rec
RESVEC, OUTFLAG = VCMP_rec(LHS, RHS, OPC) - Represents one of the altivec VCMP*_rec instructions.
@ MFFS
F8RC = MFFS - This moves the FPSCR (not modeled) into the register.
@ PADDI_DTPREL
G8RC = PADDI_DTPREL x3, Symbol - For the pc-rel based local-dynamic TLS model, produces a PADDI8 inst...
@ BUILD_FP128
Direct move of 2 consecutive GPR to a VSX register.
@ VEXTS
VEXTS, ByteWidth - takes an input in VSFRC and produces an output in VSFRC that is sign-extended from...
@ TLS_LOCAL_EXEC_MAT_ADDR
TLS_LOCAL_EXEC_MAT_ADDR = Materialize an address for TLS global address when using local exec access ...
@ VPERM
VPERM - The PPC VPERM Instruction.
@ ADDIS_TLSLD_HA
G8RC = ADDIS_TLSLD_HA x2, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction th...
@ XXSPLTI_SP_TO_DP
XXSPLTI_SP_TO_DP - The PPC VSX splat instructions for immediates for converting immediate single prec...
@ GET_TLSLD_ADDR
x3 = GET_TLSLD_ADDR x3, Symbol - For the local-dynamic TLS model, produces a call to __tls_get_addr(s...
@ ADDI_TLSGD_L
x3 = ADDI_TLSGD_L G8RReg, Symbol - For the general-dynamic TLS model, produces an ADDI8 instruction t...
@ DYNAREAOFFSET
This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to compute an offset from native ...
@ PAIR_BUILD
PAIR_BUILD = Build a vector pair register from 2 VSX registers.
@ STRICT_FADDRTZ
Constrained floating point add in round-to-zero mode.
@ FTSQRT
Test instruction for software square root.
@ FP_EXTEND_HALF
FP_EXTEND_HALF(VECTOR, IDX) - Custom extend upper (IDX=0) half or lower (IDX=1) half of v4f32 to v2f6...
@ CMPB
The CMPB instruction (takes two operands of i32 or i64).
@ VECSHL
VECSHL - The PPC vector shift left instruction.
@ ADDI_TLSLD_L
x3 = ADDI_TLSLD_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction tha...
@ FADDRTZ
F8RC = FADDRTZ F8RC, F8RC - This is an FADD done with rounding towards zero.
@ ZEXT_LD_SPLAT
VSRC, CHAIN = ZEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that zero-extends.
@ SRA_ADDZE
The combination of sra[wd]i and addze used to implemented signed integer division by a power of 2.
@ EXTSWSLI
EXTSWSLI = The PPC extswsli instruction, which does an extend-sign word and shift left immediate.
@ STXVD2X
CHAIN = STXVD2X CHAIN, VSRC, Ptr - Occurs only for little endian.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ GET_TPOINTER
x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on 32-bit AIX, produces a call to ...
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ STBRX
CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a byte-swapping store instruction.
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
const_iterator end(StringRef path)
Get end iterator over path.
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)
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.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
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,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
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)
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)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
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(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Mul
Product of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
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 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
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.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
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.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static 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.
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 & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)