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()) {
1548void PPCTargetLowering::initializeAddrModeMap() {
1599 if (MaxAlign == MaxMaxAlign)
1601 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1602 if (MaxMaxAlign >= 32 &&
1603 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1604 MaxAlign =
Align(32);
1605 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1607 MaxAlign =
Align(16);
1608 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1611 if (EltAlign > MaxAlign)
1612 MaxAlign = EltAlign;
1613 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1614 for (
auto *EltTy : STy->elements()) {
1617 if (EltAlign > MaxAlign)
1618 MaxAlign = EltAlign;
1619 if (MaxAlign == MaxMaxAlign)
1632 if (Subtarget.hasAltivec())
1634 return Alignment.
value();
1642 return Subtarget.hasSPE();
1650 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &
Index)
const {
1651 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1654 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1655 if (VTy->getScalarType()->isIntegerTy()) {
1657 if (ElemSizeInBits == 32) {
1661 if (ElemSizeInBits == 64) {
1687 return "PPCISD::FTSQRT";
1689 return "PPCISD::FSQRT";
1694 return "PPCISD::XXSPLTI_SP_TO_DP";
1696 return "PPCISD::XXSPLTI32DX";
1700 return "PPCISD::XXPERM";
1720 return "PPCISD::CALL_RM";
1722 return "PPCISD::CALL_NOP_RM";
1724 return "PPCISD::CALL_NOTOC_RM";
1729 return "PPCISD::BCTRL_RM";
1731 return "PPCISD::BCTRL_LOAD_TOC_RM";
1743 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1745 return "PPCISD::ANDI_rec_1_EQ_BIT";
1747 return "PPCISD::ANDI_rec_1_GT_BIT";
1762 return "PPCISD::ST_VSR_SCAL_INT";
1791 return "PPCISD::PADDI_DTPREL";
1807 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1809 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1819 return "PPCISD::STRICT_FADDRTZ";
1821 return "PPCISD::STRICT_FCTIDZ";
1823 return "PPCISD::STRICT_FCTIWZ";
1825 return "PPCISD::STRICT_FCTIDUZ";
1827 return "PPCISD::STRICT_FCTIWUZ";
1829 return "PPCISD::STRICT_FCFID";
1831 return "PPCISD::STRICT_FCFIDU";
1833 return "PPCISD::STRICT_FCFIDS";
1835 return "PPCISD::STRICT_FCFIDUS";
1838 return "PPCISD::STORE_COND";
1846 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1863 return CFP->getValueAPF().isZero();
1867 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1868 return CFP->getValueAPF().isZero();
1876 return Op < 0 ||
Op == Val;
1888 if (ShuffleKind == 0) {
1891 for (
unsigned i = 0; i != 16; ++i)
1894 }
else if (ShuffleKind == 2) {
1897 for (
unsigned i = 0; i != 16; ++i)
1900 }
else if (ShuffleKind == 1) {
1901 unsigned j = IsLE ? 0 : 1;
1902 for (
unsigned i = 0; i != 8; ++i)
1919 if (ShuffleKind == 0) {
1922 for (
unsigned i = 0; i != 16; i += 2)
1926 }
else if (ShuffleKind == 2) {
1929 for (
unsigned i = 0; i != 16; i += 2)
1933 }
else if (ShuffleKind == 1) {
1934 unsigned j = IsLE ? 0 : 2;
1935 for (
unsigned i = 0; i != 8; i += 2)
1956 if (!Subtarget.hasP8Vector())
1960 if (ShuffleKind == 0) {
1963 for (
unsigned i = 0; i != 16; i += 4)
1969 }
else if (ShuffleKind == 2) {
1972 for (
unsigned i = 0; i != 16; i += 4)
1978 }
else if (ShuffleKind == 1) {
1979 unsigned j = IsLE ? 0 : 4;
1980 for (
unsigned i = 0; i != 8; i += 4)
1997 unsigned LHSStart,
unsigned RHSStart) {
1998 if (
N->getValueType(0) != MVT::v16i8)
2000 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2001 "Unsupported merge size!");
2003 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2004 for (
unsigned j = 0; j != UnitSize; ++j) {
2006 LHSStart+j+i*UnitSize) ||
2008 RHSStart+j+i*UnitSize))
2023 if (ShuffleKind == 1)
2025 else if (ShuffleKind == 2)
2030 if (ShuffleKind == 1)
2032 else if (ShuffleKind == 0)
2048 if (ShuffleKind == 1)
2050 else if (ShuffleKind == 2)
2055 if (ShuffleKind == 1)
2057 else if (ShuffleKind == 0)
2107 unsigned RHSStartValue) {
2108 if (
N->getValueType(0) != MVT::v16i8)
2111 for (
unsigned i = 0; i < 2; ++i)
2112 for (
unsigned j = 0; j < 4; ++j)
2114 i*RHSStartValue+j+IndexOffset) ||
2116 i*RHSStartValue+j+IndexOffset+8))
2138 unsigned indexOffset = CheckEven ? 4 : 0;
2139 if (ShuffleKind == 1)
2141 else if (ShuffleKind == 2)
2147 unsigned indexOffset = CheckEven ? 0 : 4;
2148 if (ShuffleKind == 1)
2150 else if (ShuffleKind == 0)
2166 if (
N->getValueType(0) != MVT::v16i8)
2173 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2176 if (i == 16)
return -1;
2181 if (ShiftAmt < i)
return -1;
2186 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2188 for (++i; i != 16; ++i)
2191 }
else if (ShuffleKind == 1) {
2193 for (++i; i != 16; ++i)
2200 ShiftAmt = 16 - ShiftAmt;
2209 EVT VT =
N->getValueType(0);
2210 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2211 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2214 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2218 if (
N->getMaskElt(0) % EltSize != 0)
2223 unsigned ElementBase =
N->getMaskElt(0);
2226 if (ElementBase >= 16)
2231 for (
unsigned i = 1; i != EltSize; ++i)
2232 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2235 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2236 if (
N->getMaskElt(i) < 0)
continue;
2237 for (
unsigned j = 0; j != EltSize; ++j)
2238 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2255 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2256 "Unexpected element width.");
2257 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2259 unsigned NumOfElem = 16 / Width;
2260 unsigned MaskVal[16];
2261 for (
unsigned i = 0; i < NumOfElem; ++i) {
2262 MaskVal[0] =
N->getMaskElt(i * Width);
2263 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2265 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2269 for (
unsigned int j = 1; j < Width; ++j) {
2270 MaskVal[j] =
N->getMaskElt(i * Width + j);
2271 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2281 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2286 unsigned M0 =
N->getMaskElt(0) / 4;
2287 unsigned M1 =
N->getMaskElt(4) / 4;
2288 unsigned M2 =
N->getMaskElt(8) / 4;
2289 unsigned M3 =
N->getMaskElt(12) / 4;
2290 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2291 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2296 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2297 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2298 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2299 InsertAtByte = IsLE ? 12 : 0;
2304 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2305 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2306 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2307 InsertAtByte = IsLE ? 8 : 4;
2312 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2313 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2314 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2315 InsertAtByte = IsLE ? 4 : 8;
2320 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2321 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2322 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2323 InsertAtByte = IsLE ? 0 : 12;
2330 if (
N->getOperand(1).isUndef()) {
2333 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2334 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2335 InsertAtByte = IsLE ? 12 : 0;
2338 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2339 InsertAtByte = IsLE ? 8 : 4;
2342 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2343 InsertAtByte = IsLE ? 4 : 8;
2346 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2347 InsertAtByte = IsLE ? 0 : 12;
2356 bool &Swap,
bool IsLE) {
2357 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2363 unsigned M0 =
N->getMaskElt(0) / 4;
2364 unsigned M1 =
N->getMaskElt(4) / 4;
2365 unsigned M2 =
N->getMaskElt(8) / 4;
2366 unsigned M3 =
N->getMaskElt(12) / 4;
2370 if (
N->getOperand(1).isUndef()) {
2371 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2372 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2375 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2381 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2385 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2390 ShiftElts = (8 -
M0) % 8;
2391 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2396 ShiftElts = (4 -
M0) % 4;
2401 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2406 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2418 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2423 for (
int i = 0; i < 16; i += Width)
2424 if (
N->getMaskElt(i) != i + Width - 1)
2455 bool &Swap,
bool IsLE) {
2456 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2462 unsigned M0 =
N->getMaskElt(0) / 8;
2463 unsigned M1 =
N->getMaskElt(8) / 8;
2464 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2468 if (
N->getOperand(1).isUndef()) {
2469 if ((
M0 |
M1) < 2) {
2470 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2478 if (
M0 > 1 &&
M1 < 2) {
2480 }
else if (M0 < 2 && M1 > 1) {
2488 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2491 if (M0 < 2 && M1 > 1) {
2493 }
else if (
M0 > 1 &&
M1 < 2) {
2501 DM = (
M0 << 1) + (
M1 & 1);
2516 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2521 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2537 unsigned EltSize = 16/
N->getNumOperands();
2538 if (EltSize < ByteSize) {
2539 unsigned Multiple = ByteSize/EltSize;
2541 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2544 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2545 if (
N->getOperand(i).isUndef())
continue;
2547 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2549 if (!UniquedVals[i&(Multiple-1)].
getNode())
2550 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2551 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2561 bool LeadingZero =
true;
2562 bool LeadingOnes =
true;
2563 for (
unsigned i = 0; i != Multiple-1; ++i) {
2564 if (!UniquedVals[i].
getNode())
continue;
2571 if (!UniquedVals[Multiple-1].
getNode())
2578 if (!UniquedVals[Multiple-1].
getNode())
2580 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2589 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2590 if (
N->getOperand(i).isUndef())
continue;
2592 OpVal =
N->getOperand(i);
2593 else if (OpVal !=
N->getOperand(i))
2599 unsigned ValSizeInBytes = EltSize;
2602 Value = CN->getZExtValue();
2604 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2605 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2611 if (ValSizeInBytes < ByteSize)
return SDValue();
2622 if (MaskVal == 0)
return SDValue();
2625 if (SignExtend32<5>(MaskVal) == MaskVal)
2639 if (!isa<ConstantSDNode>(
N))
2642 Imm = (int16_t)
N->getAsZExtVal();
2643 if (
N->getValueType(0) == MVT::i32)
2644 return Imm == (int32_t)
N->getAsZExtVal();
2646 return Imm == (int64_t)
N->getAsZExtVal();
2664 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2673 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2674 if (Memop->getMemoryVT() == MVT::f64) {
2675 Base =
N.getOperand(0);
2688 if (!isa<ConstantSDNode>(
N))
2691 Imm = (int64_t)
N->getAsZExtVal();
2692 return isInt<34>(Imm);
2719 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2724 Base =
N.getOperand(0);
2727 }
else if (
N.getOpcode() ==
ISD::OR) {
2729 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2741 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2742 Base =
N.getOperand(0);
2813 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2819 Base =
N.getOperand(0);
2822 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2824 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2825 "Cannot handle constant offsets yet!");
2826 Disp =
N.getOperand(1).getOperand(0);
2831 Base =
N.getOperand(0);
2834 }
else if (
N.getOpcode() ==
ISD::OR) {
2837 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2847 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2851 Base =
N.getOperand(0);
2864 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2867 CN->getValueType(0));
2872 if ((CN->getValueType(0) == MVT::i32 ||
2873 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2874 (!EncodingAlignment ||
2875 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2876 int Addr = (int)CN->getZExtValue();
2883 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2904 if (
N.getValueType() != MVT::i64)
2917 Base =
N.getOperand(0);
2933 Base =
N.getOperand(0);
2966 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2967 Base =
N.getOperand(0);
2980 Ty *PCRelCand = dyn_cast<Ty>(
N);
2992 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
2993 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
2994 isValidPCRelNode<JumpTableSDNode>(
N) ||
2995 isValidPCRelNode<BlockAddressSDNode>(
N))
3011 EVT MemVT = LD->getMemoryVT();
3018 if (!ST.hasP8Vector())
3023 if (!ST.hasP9Vector())
3036 if (UI.getUse().get().getResNo() == 0 &&
3058 Ptr = LD->getBasePtr();
3059 VT = LD->getMemoryVT();
3060 Alignment = LD->getAlign();
3061 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3062 Ptr = ST->getBasePtr();
3063 VT = ST->getMemoryVT();
3064 Alignment = ST->getAlign();
3087 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3090 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3103 if (VT != MVT::i64) {
3108 if (Alignment <
Align(4))
3118 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3120 isa<ConstantSDNode>(
Offset))
3135 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3177 const bool Is64Bit = Subtarget.
isPPC64();
3178 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3192 EVT PtrVT =
Op.getValueType();
3208 return getTOCEntry(DAG,
SDLoc(CP), GA);
3211 unsigned MOHiFlag, MOLoFlag;
3218 return getTOCEntry(DAG,
SDLoc(CP), GA);
3278 EVT PtrVT =
Op.getValueType();
3296 return getTOCEntry(DAG,
SDLoc(JT), GA);
3299 unsigned MOHiFlag, MOLoFlag;
3306 return getTOCEntry(DAG,
SDLoc(GA), GA);
3316 EVT PtrVT =
Op.getValueType();
3335 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3344 unsigned MOHiFlag, MOLoFlag;
3355 return LowerGlobalTLSAddressAIX(
Op, DAG);
3357 return LowerGlobalTLSAddressLinux(
Op, DAG);
3381 if (
II->getOpcode() == Instruction::Call)
3382 if (
const CallInst *CI = dyn_cast<const CallInst>(&*
II))
3383 if (
Function *CF = CI->getCalledFunction())
3384 if (CF->isDeclaration() &&
3385 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3387 dyn_cast<GlobalValue>(
II->getOperand(0))) {
3393 unsigned TLSGVCnt = TLSGV.
size();
3403 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3418 bool Is64Bit = Subtarget.
isPPC64();
3422 if (Subtarget.hasAIXShLibTLSModelOpt())
3428 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3429 bool HasAIXSmallTLSGlobalAttr =
false;
3432 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3436 if (GVar->hasAttribute(
"aix-small-tls"))
3437 HasAIXSmallTLSGlobalAttr =
true;
3456 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3457 IsTLSLocalExecModel) {
3477 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3479 "currently only supported on AIX (64-bit mode).");
3485 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3489 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3491 "currently only supported on AIX (64-bit mode).");
3499 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3503 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3506 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3509 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3520 if (HasAIXSmallLocalDynamicTLS) {
3529 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3542 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3543 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3561 bool is64bit = Subtarget.
isPPC64();
3608 if (!
TM.isPositionIndependent())
3667 PtrVT, GOTPtr, TGA, TGA);
3669 PtrVT, TLSAddr, TGA);
3678 EVT PtrVT =
Op.getValueType();
3703 return getTOCEntry(DAG,
DL, GA);
3706 unsigned MOHiFlag, MOLoFlag;
3714 return getTOCEntry(DAG,
DL, GA);
3726 bool IsStrict =
Op->isStrictFPOpcode();
3728 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3732 EVT LHSVT =
LHS.getValueType();
3736 if (LHSVT == MVT::f128) {
3737 assert(!Subtarget.hasP9Vector() &&
3738 "SETCC for f128 is already legal under Power9!");
3749 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3751 if (
Op.getValueType() == MVT::v2i64) {
3754 if (
LHS.getValueType() == MVT::v2i64) {
3762 int ShuffV[] = {1, 0, 3, 2};
3767 dl, MVT::v4i32, Shuff, SetCC32));
3784 if (
C->isAllOnes() ||
C->isZero())
3794 EVT VT =
Op.getValueType();
3803 EVT VT =
Node->getValueType(0);
3807 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3817 if (VT == MVT::i64) {
3848 InChain = OverflowArea.
getValue(1);
3894 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3901 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3907 false,
true,
nullptr, std::nullopt,
3916 return Op.getOperand(0);
3925 "Expecting Inline ASM node.");
3935 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3941 unsigned NumVals =
Flags.getNumOperandRegisters();
3944 switch (
Flags.getKind()) {
3955 for (; NumVals; --NumVals, ++i) {
3956 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3957 if (Reg != PPC::LR && Reg != PPC::LR8)
3982 bool isPPC64 = (PtrVT == MVT::i64);
3988 Entry.Ty = IntPtrTy;
3989 Entry.Node = Trmp;
Args.push_back(Entry);
3993 isPPC64 ? MVT::i64 : MVT::i32);
3994 Args.push_back(Entry);
3996 Entry.Node = FPtr;
Args.push_back(Entry);
3997 Entry.Node = Nest;
Args.push_back(Entry);
4001 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4005 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4006 return CallResult.second;
4020 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4021 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4056 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4065 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4080 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4083 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4085 nextOffset += FrameOffset;
4086 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4089 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4095static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4096 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4097 PPC::F11, PPC::F12, PPC::F13};
4102 unsigned PtrByteSize) {
4104 if (Flags.isByVal())
4105 ArgSize = Flags.getByValSize();
4109 if (!Flags.isInConsecutiveRegs())
4110 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4119 unsigned PtrByteSize) {
4120 Align Alignment(PtrByteSize);
4123 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4124 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4125 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4126 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4127 Alignment =
Align(16);
4130 if (Flags.isByVal()) {
4131 auto BVAlign = Flags.getNonZeroByValAlign();
4132 if (BVAlign > PtrByteSize) {
4133 if (BVAlign.value() % PtrByteSize != 0)
4135 "ByVal alignment is not a multiple of the pointer size");
4137 Alignment = BVAlign;
4142 if (Flags.isInConsecutiveRegs()) {
4146 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4160 unsigned PtrByteSize,
unsigned LinkageSize,
4161 unsigned ParamAreaSize,
unsigned &ArgOffset,
4162 unsigned &AvailableFPRs,
4163 unsigned &AvailableVRs) {
4164 bool UseMemory =
false;
4169 ArgOffset =
alignTo(ArgOffset, Alignment);
4172 if (ArgOffset >= LinkageSize + ParamAreaSize)
4177 if (Flags.isInConsecutiveRegsLast())
4178 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4181 if (ArgOffset > LinkageSize + ParamAreaSize)
4186 if (!Flags.isByVal()) {
4187 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4188 if (AvailableFPRs > 0) {
4192 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4193 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4194 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4195 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4196 if (AvailableVRs > 0) {
4208 unsigned NumBytes) {
4212SDValue PPCTargetLowering::LowerFormalArguments(
4217 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4220 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4223 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4227SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4269 const Align PtrAlign(4);
4278 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4280 CCInfo.PreAnalyzeFormalArguments(Ins);
4283 CCInfo.clearWasPPCF128();
4285 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4298 RC = &PPC::GPRCRegClass;
4301 if (Subtarget.hasP8Vector())
4302 RC = &PPC::VSSRCRegClass;
4303 else if (Subtarget.hasSPE())
4304 RC = &PPC::GPRCRegClass;
4306 RC = &PPC::F4RCRegClass;
4309 if (Subtarget.hasVSX())
4310 RC = &PPC::VSFRCRegClass;
4311 else if (Subtarget.hasSPE())
4313 RC = &PPC::GPRCRegClass;
4315 RC = &PPC::F8RCRegClass;
4320 RC = &PPC::VRRCRegClass;
4323 RC = &PPC::VRRCRegClass;
4327 RC = &PPC::VRRCRegClass;
4334 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4335 assert(i + 1 < e &&
"No second half of double precision argument");
4347 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4348 if (ValVT == MVT::i1)
4363 ArgOffset += ArgSize - ObjSize;
4381 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4386 unsigned MinReservedArea = CCByValInfo.getStackSize();
4387 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4403 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4404 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4406 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4409 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4412 unsigned NumFPArgRegs = std::size(FPArgRegs);
4421 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4425 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4434 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4438 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4453 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4457 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4470 if (!MemOps.
empty())
4481 const SDLoc &dl)
const {
4485 else if (
Flags.isZExt())
4492SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4505 "fastcc not supported on varargs functions");
4511 unsigned PtrByteSize = 8;
4515 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4516 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4519 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4520 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4523 const unsigned Num_GPR_Regs = std::size(GPR);
4525 const unsigned Num_VR_Regs = std::size(VR);
4533 bool HasParameterArea = !isELFv2ABI || isVarArg;
4534 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4535 unsigned NumBytes = LinkageSize;
4536 unsigned AvailableFPRs = Num_FPR_Regs;
4537 unsigned AvailableVRs = Num_VR_Regs;
4538 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4539 if (Ins[i].
Flags.isNest())
4543 PtrByteSize, LinkageSize, ParamAreaSize,
4544 NumBytes, AvailableFPRs, AvailableVRs))
4545 HasParameterArea =
true;
4552 unsigned ArgOffset = LinkageSize;
4553 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4556 unsigned CurArgIdx = 0;
4557 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4559 bool needsLoad =
false;
4560 EVT ObjectVT =
Ins[ArgNo].VT;
4561 EVT OrigVT =
Ins[ArgNo].ArgVT;
4563 unsigned ArgSize = ObjSize;
4565 if (Ins[ArgNo].isOrigArg()) {
4566 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4567 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4572 unsigned CurArgOffset;
4574 auto ComputeArgOffset = [&]() {
4578 ArgOffset =
alignTo(ArgOffset, Alignment);
4579 CurArgOffset = ArgOffset;
4586 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4587 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4592 if (
Flags.isByVal()) {
4593 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4599 ObjSize =
Flags.getByValSize();
4600 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4622 if (HasParameterArea ||
4623 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4630 if (ObjSize < PtrByteSize) {
4634 if (!isLittleEndian) {
4640 if (GPR_idx != Num_GPR_Regs) {
4652 ArgOffset += PtrByteSize;
4661 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4662 if (GPR_idx == Num_GPR_Regs)
4673 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4681 ArgOffset += ArgSize;
4690 if (
Flags.isNest()) {
4695 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4696 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4704 if (GPR_idx != Num_GPR_Regs) {
4709 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4712 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4718 ArgSize = PtrByteSize;
4729 if (FPR_idx != Num_FPR_Regs) {
4732 if (ObjectVT == MVT::f32)
4734 Subtarget.hasP8Vector()
4735 ? &PPC::VSSRCRegClass
4736 : &PPC::F4RCRegClass);
4739 ? &PPC::VSFRCRegClass
4740 : &PPC::F8RCRegClass);
4755 if (ObjectVT == MVT::f32) {
4756 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4774 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4775 ArgOffset += ArgSize;
4776 if (
Flags.isInConsecutiveRegsLast())
4777 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4791 if (VR_idx != Num_VR_Regs) {
4808 if (ObjSize < ArgSize && !isLittleEndian)
4809 CurArgOffset += ArgSize - ObjSize;
4819 unsigned MinReservedArea;
4820 if (HasParameterArea)
4821 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4823 MinReservedArea = LinkageSize;
4840 int Depth = ArgOffset;
4849 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4850 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4862 if (!MemOps.
empty())
4871 unsigned ParamSize) {
4873 if (!isTailCall)
return 0;
4877 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4879 if (SPDiff < FI->getTailCallSPDelta())
4895 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4908 if (!
TM.shouldAssumeDSOLocal(CalleeGV))
4914 const Function *
F = dyn_cast<Function>(CalleeGV);
4915 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4920 F = dyn_cast<Function>(GlobalObj);
4953 if (
TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4954 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4956 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4957 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4969 const unsigned PtrByteSize = 8;
4973 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4974 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4977 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4978 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4981 const unsigned NumGPRs = std::size(GPR);
4982 const unsigned NumFPRs = 13;
4983 const unsigned NumVRs = std::size(VR);
4984 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4986 unsigned NumBytes = LinkageSize;
4987 unsigned AvailableFPRs = NumFPRs;
4988 unsigned AvailableVRs = NumVRs;
4991 if (Param.Flags.isNest())
continue;
4994 LinkageSize, ParamAreaSize, NumBytes,
4995 AvailableFPRs, AvailableVRs))
5006 auto CalleeArgEnd = CB.
arg_end();
5009 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5010 const Value* CalleeArg = *CalleeArgIter;
5011 const Value* CallerArg = &(*CallerArgIter);
5012 if (CalleeArg == CallerArg)
5020 isa<UndefValue>(CalleeArg))
5038 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5048bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5053 bool isCalleeExternalSymbol)
const {
5056 if (
DisableSCO && !TailCallOpt)
return false;
5059 if (isVarArg)
return false;
5135bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5169 if (!
C)
return nullptr;
5171 int Addr =
C->getZExtValue();
5172 if ((
Addr & 3) != 0 ||
5178 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5185struct TailCallArgumentInfo {
5190 TailCallArgumentInfo() =
default;
5200 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5201 SDValue Arg = TailCallArgs[i].Arg;
5202 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5203 int FI = TailCallArgs[i].FrameIdx;
5206 Chain, dl, Arg, FIN,
5215 int SPDiff,
const SDLoc &dl) {
5221 bool isPPC64 = Subtarget.
isPPC64();
5222 int SlotSize = isPPC64 ? 8 : 4;
5223 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5225 NewRetAddrLoc,
true);
5226 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5228 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5238 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5240 int Offset = ArgOffset + SPDiff;
5243 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5245 TailCallArgumentInfo
Info;
5247 Info.FrameIdxOp = FIN;
5255SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5260 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5261 LROpOut = getReturnAddrFrameIndex(DAG);
5279 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5287 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5310 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5320 if (!MemOpChains2.
empty())
5344SDValue PPCTargetLowering::LowerCallResult(
5352 CCRetInfo.AnalyzeCallResult(
5358 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5364 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5367 Chain =
Lo.getValue(1);
5368 InGlue =
Lo.getValue(2);
5372 Chain =
Hi.getValue(1);
5373 InGlue =
Hi.getValue(2);
5410 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5442 bool IsStrictFPCall =
false) {
5446 unsigned RetOpc = 0;
5471 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5477 if (IsStrictFPCall) {
5508 auto isLocalCallee = [&]() {
5513 !isa_and_nonnull<GlobalIFunc>(GV);
5524 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5534 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5537 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5540 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5541 return getAIXFuncEntryPointSymbolSDNode(GV);
5548 const char *SymName = S->getSymbol();
5554 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5555 return getAIXFuncEntryPointSymbolSDNode(
F);
5561 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5569 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5576 assert(Callee.getNode() &&
"What no callee?");
5582 "Expected a CALLSEQ_STARTSDNode.");
5599 SDValue MTCTROps[] = {Chain, Callee, Glue};
5600 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5641 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5656 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5660 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5661 Alignment, MMOFlags);
5668 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5675 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5687 "Nest parameter is not supported on AIX.");
5703 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5706 const bool IsPPC64 = Subtarget.
isPPC64();
5708 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5755 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5757 RegsToPass[i].second.getValueType()));
5774 assert(Mask &&
"Missing call preserved mask for calling convention");
5782SDValue PPCTargetLowering::FinishCall(
5797 if (!CFlags.IsIndirect)
5801 dl, CFlags.HasNest, Subtarget);
5811 if (CFlags.IsTailCall) {
5815 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5818 isa<ConstantSDNode>(Callee) ||
5820 "Expecting a global address, external symbol, absolute value, "
5821 "register or an indirect tail call when PC Relative calls are "
5825 "Unexpected call opcode for a tail call.");
5832 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5833 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5845 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5848 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5859 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5868 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5869 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5873bool PPCTargetLowering::isEligibleForTCO(
5878 bool isCalleeExternalSymbol)
const {
5883 return IsEligibleForTailCallOptimization_64SVR4(
5884 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5885 isCalleeExternalSymbol);
5887 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5910 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5912 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5915 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5929 isa<GlobalAddressSDNode>(Callee)) &&
5930 "Callee should be an llvm::Function object.");
5933 <<
"\nTCO callee: ");
5940 "site marked musttail");
5945 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5947 Callee = LowerGlobalAddress(Callee, DAG);
5950 CallConv, isTailCall, isVarArg, isPatchPoint,
5958 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5963 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5965 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5969SDValue PPCTargetLowering::LowerCall_32SVR4(
5980 const bool IsVarArg = CFlags.IsVarArg;
5981 const bool IsTailCall = CFlags.IsTailCall;
5987 const Align PtrAlign(4);
6012 CCInfo.PreAnalyzeCallOperands(Outs);
6018 unsigned NumArgs = Outs.
size();
6020 for (
unsigned i = 0; i != NumArgs; ++i) {
6021 MVT ArgVT = Outs[i].VT;
6025 if (Outs[i].IsFixed) {
6035 errs() <<
"Call operand #" << i <<
" has unhandled type "
6045 CCInfo.clearWasPPCF128();
6052 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6059 unsigned NumBytes = CCByValInfo.getStackSize();
6073 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6084 bool seenFloatArg =
false;
6089 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6091 ++i, ++RealArgIdx) {
6093 SDValue Arg = OutVals[RealArgIdx];
6096 if (
Flags.isByVal()) {
6101 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6124 Chain = CallSeqStart = NewCallSeqStart;
6143 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6150 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6174 if (!MemOpChains.
empty())
6180 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6181 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6182 RegsToPass[i].second, InGlue);
6190 SDValue Ops[] = { Chain, InGlue };
6202 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6203 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6208SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6220 return NewCallSeqStart;
6223SDValue PPCTargetLowering::LowerCall_64SVR4(
6232 unsigned NumOps = Outs.
size();
6233 bool IsSibCall =
false;
6237 unsigned PtrByteSize = 8;
6252 assert(!(IsFastCall && CFlags.IsVarArg) &&
6253 "fastcc not supported on varargs functions");
6260 unsigned NumBytes = LinkageSize;
6261 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6264 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6265 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6268 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6269 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6272 const unsigned NumGPRs = std::size(GPR);
6274 const unsigned NumVRs = std::size(VR);
6280 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6281 if (!HasParameterArea) {
6282 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6283 unsigned AvailableFPRs = NumFPRs;
6284 unsigned AvailableVRs = NumVRs;
6285 unsigned NumBytesTmp = NumBytes;
6286 for (
unsigned i = 0; i != NumOps; ++i) {
6287 if (Outs[i].
Flags.isNest())
continue;
6289 PtrByteSize, LinkageSize, ParamAreaSize,
6290 NumBytesTmp, AvailableFPRs, AvailableVRs))
6291 HasParameterArea =
true;
6297 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6302 HasParameterArea =
false;
6305 for (
unsigned i = 0; i != NumOps; ++i) {
6307 EVT ArgVT = Outs[i].VT;
6308 EVT OrigVT = Outs[i].ArgVT;
6314 if (
Flags.isByVal()) {
6315 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6316 if (NumGPRsUsed > NumGPRs)
6317 HasParameterArea =
true;
6324 if (++NumGPRsUsed <= NumGPRs)
6334 if (++NumVRsUsed <= NumVRs)
6338 if (++NumVRsUsed <= NumVRs)
6343 if (++NumFPRsUsed <= NumFPRs)
6347 HasParameterArea =
true;
6354 NumBytes =
alignTo(NumBytes, Alignement);
6357 if (
Flags.isInConsecutiveRegsLast())
6358 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6361 unsigned NumBytesActuallyUsed = NumBytes;
6371 if (HasParameterArea)
6372 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6374 NumBytes = LinkageSize;
6389 if (CFlags.IsTailCall)
6401 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6412 unsigned ArgOffset = LinkageSize;
6418 for (
unsigned i = 0; i != NumOps; ++i) {
6421 EVT ArgVT = Outs[i].VT;
6422 EVT OrigVT = Outs[i].ArgVT;
6431 auto ComputePtrOff = [&]() {
6435 ArgOffset =
alignTo(ArgOffset, Alignment);
6446 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6447 GPR_idx = std::min(GPR_idx, NumGPRs);
6454 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6460 if (
Flags.isByVal()) {
6478 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6479 if (GPR_idx != NumGPRs) {
6483 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6485 ArgOffset += PtrByteSize;
6490 if (GPR_idx == NumGPRs &&
Size < 8) {
6492 if (!isLittleEndian) {
6497 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6500 ArgOffset += PtrByteSize;
6509 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6510 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6515 if (
Size < 8 && GPR_idx != NumGPRs) {
6525 if (!isLittleEndian) {
6529 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6537 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6540 ArgOffset += PtrByteSize;
6546 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6549 if (GPR_idx != NumGPRs) {
6550 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6556 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6557 ArgOffset += PtrByteSize;
6559 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6571 if (
Flags.isNest()) {
6573 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6580 if (GPR_idx != NumGPRs) {
6581 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6586 assert(HasParameterArea &&
6587 "Parameter area must exist to pass an argument in memory.");
6589 true, CFlags.IsTailCall,
false, MemOpChains,
6590 TailCallArguments, dl);
6592 ArgOffset += PtrByteSize;
6595 ArgOffset += PtrByteSize;
6608 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6609 bool NeededLoad =
false;
6612 if (FPR_idx != NumFPRs)
6613 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6616 if (!NeedGPROrStack)
6618 else if (GPR_idx != NumGPRs && !IsFastCall) {
6632 }
else if (!
Flags.isInConsecutiveRegs()) {
6638 }
else if (ArgOffset % PtrByteSize != 0) {
6642 if (!isLittleEndian)
6647 }
else if (
Flags.isInConsecutiveRegsLast()) {
6650 if (!isLittleEndian)
6660 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6668 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6673 assert(HasParameterArea &&
6674 "Parameter area must exist to pass an argument in memory.");
6676 true, CFlags.IsTailCall,
false, MemOpChains,
6677 TailCallArguments, dl);
6684 if (!IsFastCall || NeededLoad) {
6686 Flags.isInConsecutiveRegs()) ? 4 : 8;
6687 if (
Flags.isInConsecutiveRegsLast())
6688 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6708 if (CFlags.IsVarArg) {
6709 assert(HasParameterArea &&
6710 "Parameter area must exist if we have a varargs call.");
6716 if (VR_idx != NumVRs) {
6720 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6723 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6724 if (GPR_idx == NumGPRs)
6731 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6737 if (VR_idx != NumVRs) {
6738 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6743 assert(HasParameterArea &&
6744 "Parameter area must exist to pass an argument in memory.");
6746 true, CFlags.IsTailCall,
true, MemOpChains,
6747 TailCallArguments, dl);
6758 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6759 "mismatch in size of parameter area");
6760 (void)NumBytesActuallyUsed;
6762 if (!MemOpChains.
empty())
6768 if (CFlags.IsIndirect) {
6772 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6787 if (isELFv2ABI && !CFlags.IsPatchPoint)
6788 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6794 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6795 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6796 RegsToPass[i].second, InGlue);
6800 if (CFlags.IsTailCall && !IsSibCall)
6804 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6805 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6812 "Required alignment greater than stack alignment.");
6832 return RequiredAlign <= 8;
6837 return RequiredAlign <= 4;
6847 const bool IsPPC64 = Subtarget.
isPPC64();
6848 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6849 const Align PtrAlign(PtrSize);
6850 const Align StackAlign(16);
6851 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6853 if (ValVT == MVT::f128)
6860 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6861 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6863 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6864 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6867 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6868 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6869 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6875 if (ByValAlign > StackAlign)
6877 "16 are not supported.");
6880 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6884 if (ByValSize == 0) {
6892 while (NextReg != GPRs.
size() &&
6898 assert(Reg &&
"Alocating register unexpectedly failed.");
6903 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6924 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6953 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6955 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6988 const unsigned VecSize = 16;
6989 const Align VecAlign(VecSize);
7009 while (NextRegIndex != GPRs.
size() &&
7014 assert(Reg &&
"Allocating register unexpectedly failed.");
7027 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7039 if (NextRegIndex == GPRs.
size()) {
7048 if (GPRs[NextRegIndex] == PPC::R9) {
7053 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
7054 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
7055 assert(FirstReg && SecondReg &&
7056 "Allocating R9 or R10 unexpectedly failed.");
7070 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7072 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7087 assert((IsPPC64 || SVT != MVT::i64) &&
7088 "i64 should have been split for 32-bit codegen.");
7096 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7098 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7100 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7108 return &PPC::VRRCRegClass;
7121 else if (Flags.isZExt())
7131 if (PPC::GPRCRegClass.
contains(Reg)) {
7132 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7133 "Reg must be a valid argument register!");
7134 return LASize + 4 * (Reg - PPC::R3);
7137 if (PPC::G8RCRegClass.
contains(Reg)) {
7138 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7139 "Reg must be a valid argument register!");
7140 return LASize + 8 * (Reg - PPC::X3);
7186SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7193 "Unexpected calling convention!");
7203 const bool IsPPC64 = Subtarget.
isPPC64();
7204 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7216 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7217 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7235 auto HandleMemLoc = [&]() {
7238 assert((ValSize <= LocSize) &&
7239 "Object size is larger than size of MemLoc");
7242 if (LocSize > ValSize)
7243 CurArgOffset += LocSize - ValSize;
7245 const bool IsImmutable =
7260 assert(isVarArg &&
"Only use custom memloc for vararg.");
7263 const unsigned OriginalValNo = VA.
getValNo();
7264 (void)OriginalValNo;
7266 auto HandleCustomVecRegLoc = [&]() {
7267 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7268 "Missing custom RegLoc.");
7271 "Unexpected Val type for custom RegLoc.");
7273 "ValNo mismatch between custom MemLoc and RegLoc.");
7277 Subtarget.hasVSX()));
7284 HandleCustomVecRegLoc();
7285 HandleCustomVecRegLoc();
7289 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7291 "Only 2 custom RegLocs expected for 64-bit codegen.");
7292 HandleCustomVecRegLoc();
7293 HandleCustomVecRegLoc();
7337 const unsigned Size =
7349 if (
Flags.isByVal()) {
7355 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7364 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7366 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7379 CopyFrom.
getValue(1), dl, CopyFrom,
7389 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7392 "RegLocs should be for ByVal argument.");
7399 if (
Offset != StackSize) {
7401 "Expected MemLoc for remaining bytes.");
7402 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7416 Subtarget.hasVSX()));
7433 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7435 unsigned CallerReservedArea = std::max<unsigned>(
7436 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7442 CallerReservedArea =
7451 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7452 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7454 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7455 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7456 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7461 for (
unsigned GPRIndex =
7462 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7463 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7466 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7467 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7479 if (!MemOps.
empty())
7485SDValue PPCTargetLowering::LowerCall_AIX(
7498 "Unexpected calling convention!");
7500 if (CFlags.IsPatchPoint)
7507 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7515 const bool IsPPC64 = Subtarget.
isPPC64();
7517 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7518 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7519 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7527 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7528 const unsigned NumBytes = std::max<unsigned>(
7529 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7545 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7546 const unsigned ValNo = ArgLocs[
I].getValNo();
7550 if (
Flags.isByVal()) {
7551 const unsigned ByValSize =
Flags.getByValSize();
7559 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7568 unsigned LoadOffset = 0;
7571 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7574 LoadOffset += PtrByteSize;
7577 "Unexpected location for pass-by-value argument.");
7581 if (LoadOffset == ByValSize)
7585 assert(ArgLocs[
I].getValNo() == ValNo &&
7586 "Expected additional location for by-value argument.");
7588 if (ArgLocs[
I].isMemLoc()) {
7589 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7594 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7600 CallSeqStart, MemcpyFlags, DAG, dl);
7609 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7610 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7611 "Unexpected register residue for by-value argument.");
7613 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7617 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7627 "Unexpected load emitted during handling of pass-by-value "
7635 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7670 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7678 const unsigned OriginalValNo = VA.
getValNo();
7680 unsigned LoadOffset = 0;
7681 auto HandleCustomVecRegLoc = [&]() {
7682 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7683 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7684 "Expected custom RegLoc.");
7687 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7693 LoadOffset += PtrByteSize;
7699 HandleCustomVecRegLoc();
7700 HandleCustomVecRegLoc();
7702 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7703 ArgLocs[
I].getValNo() == OriginalValNo) {
7705 "Only 2 custom RegLocs expected for 64-bit codegen.");
7706 HandleCustomVecRegLoc();
7707 HandleCustomVecRegLoc();
7725 "Unexpected register handling for calling convention.");
7731 "Custom register handling only expected for VarArg.");
7749 "Unexpected custom register for argument!");
7770 if (!MemOpChains.
empty())
7775 if (CFlags.IsIndirect) {
7776 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7779 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7780 const unsigned TOCSaveOffset =
7796 for (
auto Reg : RegsToPass) {
7801 const int SPDiff = 0;
7802 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7803 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7812 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7813 return CCInfo.CheckReturn(
7828 CCInfo.AnalyzeReturn(Outs,
7837 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7841 SDValue Arg = OutVals[RealResIdx];
7856 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7879 RetOps.push_back(Glue);
7885PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7890 EVT IntVT =
Op.getValueType();
7894 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7896 SDValue Ops[2] = {Chain, FPSIdx};
7910 bool isPPC64 = Subtarget.
isPPC64();
7911 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7931 bool isPPC64 = Subtarget.
isPPC64();
7952PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7954 bool isPPC64 = Subtarget.
isPPC64();
7988 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7989 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8000 bool isPPC64 = Subtarget.
isPPC64();
8012 Op.getOperand(0),
Op.getOperand(1));
8019 Op.getOperand(0),
Op.getOperand(1));
8023 if (
Op.getValueType().isVector())
8024 return LowerVectorLoad(
Op, DAG);
8026 assert(
Op.getValueType() == MVT::i1 &&
8027 "Custom lowering only for i1 loads");
8040 BasePtr, MVT::i8, MMO);
8048 if (
Op.getOperand(1).getValueType().isVector())
8049 return LowerVectorStore(
Op, DAG);
8051 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8052 "Custom lowering only for i1 stores");
8071 assert(
Op.getValueType() == MVT::i1 &&
8072 "Custom lowering only for i1 results");
8100 EVT TrgVT =
Op.getValueType();
8113 !llvm::has_single_bit<uint32_t>(
8124 if (SrcSize == 256) {
8135 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8143 for (
unsigned i = 0; i < TrgNumElts; ++i)
8146 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8150 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8163 EVT ResVT =
Op.getValueType();
8164 EVT CmpVT =
Op.getOperand(0).getValueType();
8166 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8172 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8189 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8221 if (
LHS.getValueType() == MVT::f32)
8234 if (
LHS.getValueType() == MVT::f32)
8243 if (
LHS.getValueType() == MVT::f32)
8257 if (
Cmp.getValueType() == MVT::f32)
8267 if (
Cmp.getValueType() == MVT::f32)
8273 if (
Cmp.getValueType() == MVT::f32)
8279 if (
Cmp.getValueType() == MVT::f32)
8285 if (
Cmp.getValueType() == MVT::f32)
8318 bool IsStrict =
Op->isStrictFPOpcode();
8324 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8327 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8329 MVT DestTy =
Op.getSimpleValueType();
8330 assert(Src.getValueType().isFloatingPoint() &&
8331 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8332 DestTy == MVT::i64) &&
8333 "Invalid FP_TO_INT types");
8334 if (Src.getValueType() == MVT::f32) {
8338 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8339 Chain = Src.getValue(1);
8343 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8344 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8353 assert((IsSigned || Subtarget.hasFPCVT()) &&
8354 "i64 FP_TO_UINT is supported only with FPCVT");
8357 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8361 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8364 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8369void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8371 const SDLoc &dl)
const {
8375 bool IsStrict =
Op->isStrictFPOpcode();
8378 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8379 (IsSigned || Subtarget.hasFPCVT());
8381 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8390 Alignment =
Align(4);
8393 SDValue Ops[] = { Chain, Tmp, FIPtr };
8395 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8397 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8401 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8410 RLI.Alignment = Alignment;
8418 const SDLoc &dl)
const {
8421 if (
Op->isStrictFPOpcode())
8428 const SDLoc &dl)
const {
8429 bool IsStrict =
Op->isStrictFPOpcode();
8432 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8433 EVT SrcVT = Src.getValueType();
8434 EVT DstVT =
Op.getValueType();
8437 if (SrcVT == MVT::f128)
8438 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8442 if (SrcVT == MVT::ppcf128) {
8443 if (DstVT == MVT::i32) {
8448 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8459 {Op.getOperand(0), Lo, Hi}, Flags);
8462 {Res.getValue(1), Res}, Flags);
8468 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8492 {Chain, Src, FltOfs}, Flags);
8496 {Chain, Val}, Flags);
8499 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8517 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8518 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8521 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8523 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8524 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8535bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8540 if (
Op->isStrictFPOpcode())
8545 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8549 Op.getOperand(0).getValueType())) {
8551 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8556 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8557 LD->isNonTemporal())
8559 if (
LD->getMemoryVT() != MemVT)
8569 RLI.Ptr =
LD->getBasePtr();
8570 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8572 "Non-pre-inc AM on PPC?");
8577 RLI.Chain =
LD->getChain();
8578 RLI.MPI =
LD->getPointerInfo();
8579 RLI.IsDereferenceable =
LD->isDereferenceable();
8580 RLI.IsInvariant =
LD->isInvariant();
8581 RLI.Alignment =
LD->getAlign();
8582 RLI.AAInfo =
LD->getAAInfo();
8583 RLI.Ranges =
LD->getRanges();
8585 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8593void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8599 SDLoc dl(NewResChain);
8602 NewResChain, DAG.
getUNDEF(MVT::Other));
8604 "A new TF really is required here");
8613bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8614 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8621 if (!Subtarget.hasP9Vector() &&
8630 if (UI.getUse().get().getResNo() != 0)
8652 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8656 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8659 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8660 if (
Op->isStrictFPOpcode()) {
8662 Chain =
Op.getOperand(0);
8664 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8666 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8674 const SDLoc &dl)
const {
8675 assert((
Op.getValueType() == MVT::f32 ||
8676 Op.getValueType() == MVT::f64) &&
8677 "Invalid floating point type as target of conversion");
8678 assert(Subtarget.hasFPCVT() &&
8679 "Int to FP conversions with direct moves require FPCVT");
8680 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8681 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8703 for (
unsigned i = 1; i < NumConcat; ++i)
8710 const SDLoc &dl)
const {
8711 bool IsStrict =
Op->isStrictFPOpcode();
8712 unsigned Opc =
Op.getOpcode();
8713 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8716 "Unexpected conversion type");
8717 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8718 "Supports conversions to v2f64/v4f32 only.");
8722 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8725 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8730 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8733 for (
unsigned i = 0; i < WideNumElts; ++i)
8736 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8737 int SaveElts = FourEltRes ? 4 : 2;
8739 for (
int i = 0; i < SaveElts; i++)
8740 ShuffV[i * Stride] = i;
8742 for (
int i = 1; i <= SaveElts; i++)
8743 ShuffV[i * Stride - 1] = i - 1;
8751 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8752 EVT ExtVT = Src.getValueType();
8753 if (Subtarget.hasP9Altivec())
8764 {Op.getOperand(0), Extend}, Flags);
8766 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8774 bool IsStrict =
Op->isStrictFPOpcode();
8775 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8780 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8782 EVT InVT = Src.getValueType();
8783 EVT OutVT =
Op.getValueType();
8786 return LowerINT_TO_FPVector(
Op, DAG, dl);
8789 if (
Op.getValueType() == MVT::f128)
8790 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8793 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8796 if (Src.getValueType() == MVT::i1) {
8808 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8809 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8810 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8812 assert((IsSigned || Subtarget.hasFPCVT()) &&
8813 "UINT_TO_FP is supported only with FPCVT");
8815 if (Src.getValueType() == MVT::i64) {
8827 if (
Op.getValueType() == MVT::f32 &&
8828 !Subtarget.hasFPCVT() &&
8869 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8870 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8871 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8872 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8873 }
else if (Subtarget.hasLFIWAX() &&
8874 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8877 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8878 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8881 Ops, MVT::i32, MMO);
8882 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8883 }
else if (Subtarget.hasFPCVT() &&
8884 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8887 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8888 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8891 Ops, MVT::i32, MMO);
8892 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8893 }
else if (((Subtarget.hasLFIWAX() &&
8895 (Subtarget.hasFPCVT() &&
8909 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8910 "Expected an i32 store");
8916 RLI.Alignment =
Align(4);
8920 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8921 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8924 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8925 Ops, MVT::i32, MMO);
8926 Chain =
Bits.getValue(1);
8932 Chain =
FP.getValue(1);
8934 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8938 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8946 assert(Src.getValueType() == MVT::i32 &&
8947 "Unhandled INT_TO_FP type in custom expander!");
8957 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8960 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8969 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8970 "Expected an i32 store");
8976 RLI.Alignment =
Align(4);
8981 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8982 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8984 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
8988 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8991 "i32->FP without LFIWAX supported only on PPC64");
9000 Chain, dl, Ext64, FIdx,
9006 MVT::f64, dl, Chain, FIdx,
9014 Chain =
FP.getValue(1);
9015 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9019 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
9050 EVT VT =
Op.getValueType();
9056 Chain =
MFFS.getValue(1);
9070 "Stack slot adjustment is valid only on big endian subtargets!");
9100 EVT VT =
Op.getValueType();
9104 VT ==
Op.getOperand(1).getValueType() &&
9124 SDValue OutOps[] = { OutLo, OutHi };
9129 EVT VT =
Op.getValueType();
9133 VT ==
Op.getOperand(1).getValueType() &&
9153 SDValue OutOps[] = { OutLo, OutHi };
9159 EVT VT =
Op.getValueType();
9162 VT ==
Op.getOperand(1).getValueType() &&
9182 SDValue OutOps[] = { OutLo, OutHi };
9189 EVT VT =
Op.getValueType();
9196 EVT AmtVT =
Z.getValueType();
9219 static const MVT VTys[] = {
9220 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9223 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9226 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9231 EVT CanonicalVT = VTys[SplatSize-1];
9240 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9241 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9250 EVT DestVT = MVT::Other) {
9251 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9260 EVT DestVT = MVT::Other) {
9263 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9275 for (
unsigned i = 0; i != 16; ++i)
9296 EVT VecVT = V->getValueType(0);
9297 bool RightType = VecVT == MVT::v2f64 ||
9298 (HasP8Vector && VecVT == MVT::v4f32) ||
9299 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9303 bool IsSplat =
true;
9304 bool IsLoad =
false;
9305 SDValue Op0 = V->getOperand(0);
9310 if (V->isConstant())
9312 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9313 if (V->getOperand(i).isUndef())
9317 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9319 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9321 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9323 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9327 if (V->getOperand(i) != Op0 ||
9328 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9331 return !(IsSplat && IsLoad);
9340 if ((
Op.getValueType() != MVT::f128) ||
9361 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9369 APFloat APFloatToConvert = ArgAPFloat;
9370 bool LosesInfo =
true;
9375 ArgAPFloat = APFloatToConvert;
9397 APFloat APFloatToConvert = ArgAPFloat;
9398 bool LosesInfo =
true;
9402 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9407 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9411 EVT Ty =
Op->getValueType(0);
9414 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9423 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9427 if (Ty == MVT::v2i64) {
9430 if (MemVT == MVT::i32) {
9450 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9453 APInt APSplatBits, APSplatUndef;
9454 unsigned SplatBitSize;
9456 bool BVNIsConstantSplat =
9464 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9465 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9468 if ((
Op->getValueType(0) == MVT::v2f64) &&
9503 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9510 const SDValue *InputLoad = &
Op.getOperand(0);
9515 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9516 unsigned ElementSize =
9519 assert(((ElementSize == 2 * MemorySize)
9523 "Unmatched element size and opcode!\n");
9528 unsigned NumUsesOfInputLD = 128 / ElementSize;
9530 if (BVInOp.isUndef())
9545 if (NumUsesOfInputLD == 1 &&
9548 Subtarget.hasLFIWAX()))
9557 Subtarget.isISA3_1() && ElementSize <= 16)
9560 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9562 Subtarget.hasVSX()) {
9569 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9570 LD->getMemoryVT(),
LD->getMemOperand());
9582 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9584 Subtarget.hasP8Vector()))
9591 unsigned SplatSize = SplatBitSize / 8;
9596 if (SplatBits == 0) {
9598 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9610 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9612 Op.getValueType(), DAG, dl);
9614 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9619 if (Subtarget.hasP9Vector() && SplatSize == 1)
9624 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9626 if (SextVal >= -16 && SextVal <= 15)
9639 if (SextVal >= -32 && SextVal <= 31) {
9644 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9645 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9648 if (VT ==
Op.getValueType())
9657 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9671 static const signed char SplatCsts[] = {
9672 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9673 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9676 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9679 int i = SplatCsts[idx];
9683 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9686 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9688 static const unsigned IIDs[] = {
9689 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9690 Intrinsic::ppc_altivec_vslw
9697 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9699 static const unsigned IIDs[] = {
9700 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9701 Intrinsic::ppc_altivec_vsrw
9708 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9709 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9711 static const unsigned IIDs[] = {
9712 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9713 Intrinsic::ppc_altivec_vrlw
9720 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9726 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9732 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9747 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9748 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9749 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9765 if (LHSID == (1*9+2)*9+3)
return LHS;
9766 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9778 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9779 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9780 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9781 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9784 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9785 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9786 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9787 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9790 for (
unsigned i = 0; i != 16; ++i)
9791 ShufIdxs[i] = (i&3)+0;
9794 for (
unsigned i = 0; i != 16; ++i)
9795 ShufIdxs[i] = (i&3)+4;
9798 for (
unsigned i = 0; i != 16; ++i)
9799 ShufIdxs[i] = (i&3)+8;
9802 for (
unsigned i = 0; i != 16; ++i)
9803 ShufIdxs[i] = (i&3)+12;
9824 const unsigned BytesInVector = 16;
9829 unsigned ShiftElts = 0, InsertAtByte = 0;
9833 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9834 0, 15, 14, 13, 12, 11, 10, 9};
9835 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9836 1, 2, 3, 4, 5, 6, 7, 8};
9839 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9851 bool FoundCandidate =
false;
9855 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9858 for (
unsigned i = 0; i < BytesInVector; ++i) {
9859 unsigned CurrentElement =
Mask[i];
9862 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9865 bool OtherElementsInOrder =
true;
9868 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9875 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9876 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9877 OtherElementsInOrder =
false;
9884 if (OtherElementsInOrder) {
9891 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9892 : BigEndianShifts[CurrentElement & 0xF];
9893 Swap = CurrentElement < BytesInVector;
9895 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9896 FoundCandidate =
true;
9901 if (!FoundCandidate)
9925 const unsigned NumHalfWords = 8;
9926 const unsigned BytesInVector = NumHalfWords * 2;
9935 unsigned ShiftElts = 0, InsertAtByte = 0;
9939 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9940 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9943 uint32_t OriginalOrderLow = 0x1234567;
9944 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9947 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9948 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9965 bool FoundCandidate =
false;
9968 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9969 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9979 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9980 TargetOrder = OriginalOrderLow;
9984 if (MaskOneElt == VINSERTHSrcElem &&
9985 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9986 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9987 FoundCandidate =
true;
9993 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9995 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9997 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9998 : BigEndianShifts[MaskOneElt & 0x7];
9999 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10000 Swap = MaskOneElt < NumHalfWords;
10001 FoundCandidate =
true;
10007 if (!FoundCandidate)
10042 auto ShuffleMask = SVN->
getMask();
10057 ShuffleMask = CommutedSV->
getMask();
10066 APInt APSplatValue, APSplatUndef;
10067 unsigned SplatBitSize;
10083 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10084 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10085 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10087 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10088 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10089 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10097 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10098 SplatVal |= (SplatVal << SplatBitSize);
10112 assert(
Op.getValueType() == MVT::v1i128 &&
10113 "Only set v1i128 as custom, other type shouldn't reach here!");
10118 if (SHLAmt % 8 == 0) {
10119 std::array<int, 16>
Mask;
10120 std::iota(
Mask.begin(),
Mask.end(), 0);
10121 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10150 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10151 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10154 SVOp = cast<ShuffleVectorSDNode>(
Op);
10155 V1 =
Op.getOperand(0);
10156 V2 =
Op.getOperand(1);
10158 EVT VT =
Op.getValueType();
10161 unsigned ShiftElts, InsertAtByte;
10167 bool IsPermutedLoad =
false;
10169 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10179 if (IsPermutedLoad) {
10180 assert((isLittleEndian || IsFourByte) &&
10181 "Unexpected size for permuted load on big endian target");
10182 SplatIdx += IsFourByte ? 2 : 1;
10183 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10184 "Splat of a value outside of the loaded memory");
10189 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10192 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10194 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10198 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10211 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10214 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10223 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10226 if (Subtarget.hasP9Vector() &&
10247 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10249 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10250 return SplatInsertNode;
10253 if (Subtarget.hasP9Altivec()) {
10255 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10258 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10262 if (Subtarget.hasVSX() &&
10275 if (Subtarget.hasVSX() &&
10288 if (Subtarget.hasP9Vector()) {
10308 if (Subtarget.hasVSX()) {
10329 if (
V2.isUndef()) {
10342 (Subtarget.hasP8Altivec() && (
10353 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10363 (Subtarget.hasP8Altivec() && (
10374 unsigned PFIndexes[4];
10375 bool isFourElementShuffle =
true;
10376 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10378 unsigned EltNo = 8;
10379 for (
unsigned j = 0;
j != 4; ++
j) {
10380 if (PermMask[i * 4 + j] < 0)
10383 unsigned ByteSource = PermMask[i * 4 +
j];
10384 if ((ByteSource & 3) != j) {
10385 isFourElementShuffle =
false;
10390 EltNo = ByteSource / 4;
10391 }
else if (EltNo != ByteSource / 4) {
10392 isFourElementShuffle =
false;
10396 PFIndexes[i] = EltNo;
10404 if (isFourElementShuffle) {
10406 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10407 PFIndexes[2] * 9 + PFIndexes[3];
10410 unsigned Cost = (PFEntry >> 30);
10430 if (
V2.isUndef())
V2 = V1;
10432 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10441 bool NeedSwap =
false;
10443 bool isPPC64 = Subtarget.
isPPC64();
10445 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10447 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10448 "XXPERM instead\n");
10454 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10455 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10457 NeedSwap = !NeedSwap;
10492 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10494 if (V1HasXXSWAPD) {
10497 else if (SrcElt < 16)
10500 if (V2HasXXSWAPD) {
10503 else if (SrcElt > 15)
10512 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10513 if (isLittleEndian)
10515 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10518 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10521 if (V1HasXXSWAPD) {
10525 if (V2HasXXSWAPD) {
10526 dl =
SDLoc(
V2->getOperand(0));
10527 V2 =
V2->getOperand(0)->getOperand(1);
10530 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10531 if (ValType != MVT::v2f64)
10533 if (
V2.getValueType() != MVT::v2f64)
10537 ShufflesHandledWithVPERM++;
10542 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10544 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10547 dbgs() <<
"With the following permute control vector:\n";
10552 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10556 if (isLittleEndian)
10562 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10574 switch (IntrinsicID) {
10578 case Intrinsic::ppc_altivec_vcmpbfp_p:
10582 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10586 case Intrinsic::ppc_altivec_vcmpequb_p:
10590 case Intrinsic::ppc_altivec_vcmpequh_p:
10594 case Intrinsic::ppc_altivec_vcmpequw_p:
10598 case Intrinsic::ppc_altivec_vcmpequd_p:
10599 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10605 case Intrinsic::ppc_altivec_vcmpneb_p:
10606 case Intrinsic::ppc_altivec_vcmpneh_p:
10607 case Intrinsic::ppc_altivec_vcmpnew_p:
10608 case Intrinsic::ppc_altivec_vcmpnezb_p:
10609 case Intrinsic::ppc_altivec_vcmpnezh_p:
10610 case Intrinsic::ppc_altivec_vcmpnezw_p:
10611 if (Subtarget.hasP9Altivec()) {
10612 switch (IntrinsicID) {
10615 case Intrinsic::ppc_altivec_vcmpneb_p:
10618 case Intrinsic::ppc_altivec_vcmpneh_p:
10621 case Intrinsic::ppc_altivec_vcmpnew_p:
10624 case Intrinsic::ppc_altivec_vcmpnezb_p:
10627 case Intrinsic::ppc_altivec_vcmpnezh_p:
10630 case Intrinsic::ppc_altivec_vcmpnezw_p:
10638 case Intrinsic::ppc_altivec_vcmpgefp_p:
10642 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10646 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10650 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10654 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10658 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10659 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10665 case Intrinsic::ppc_altivec_vcmpgtub_p:
10669 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10673 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10677 case Intrinsic::ppc_altivec_vcmpgtud_p:
10678 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10685 case Intrinsic::ppc_altivec_vcmpequq:
10686 case Intrinsic::ppc_altivec_vcmpgtsq:
10687 case Intrinsic::ppc_altivec_vcmpgtuq:
10688 if (!Subtarget.isISA3_1())
10690 switch (IntrinsicID) {
10693 case Intrinsic::ppc_altivec_vcmpequq:
10696 case Intrinsic::ppc_altivec_vcmpgtsq:
10699 case Intrinsic::ppc_altivec_vcmpgtuq:
10706 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10707 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10708 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10709 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10710 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10711 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10712 if (Subtarget.hasVSX()) {
10713 switch (IntrinsicID) {
10714 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10717 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10720 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10723 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10726 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10729 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10739 case Intrinsic::ppc_altivec_vcmpbfp:
10742 case Intrinsic::ppc_altivec_vcmpeqfp:
10745 case Intrinsic::ppc_altivec_vcmpequb:
10748 case Intrinsic::ppc_altivec_vcmpequh:
10751 case Intrinsic::ppc_altivec_vcmpequw:
10754 case Intrinsic::ppc_altivec_vcmpequd:
10755 if (Subtarget.hasP8Altivec())
10760 case Intrinsic::ppc_altivec_vcmpneb:
10761 case Intrinsic::ppc_altivec_vcmpneh:
10762 case Intrinsic::ppc_altivec_vcmpnew:
10763 case Intrinsic::ppc_altivec_vcmpnezb:
10764 case Intrinsic::ppc_altivec_vcmpnezh:
10765 case Intrinsic::ppc_altivec_vcmpnezw:
10766 if (Subtarget.hasP9Altivec())
10767 switch (IntrinsicID) {
10770 case Intrinsic::ppc_altivec_vcmpneb:
10773 case Intrinsic::ppc_altivec_vcmpneh:
10776 case Intrinsic::ppc_altivec_vcmpnew:
10779 case Intrinsic::ppc_altivec_vcmpnezb:
10782 case Intrinsic::ppc_altivec_vcmpnezh:
10785 case Intrinsic::ppc_altivec_vcmpnezw:
10792 case Intrinsic::ppc_altivec_vcmpgefp:
10795 case Intrinsic::ppc_altivec_vcmpgtfp:
10798 case Intrinsic::ppc_altivec_vcmpgtsb:
10801 case Intrinsic::ppc_altivec_vcmpgtsh:
10804 case Intrinsic::ppc_altivec_vcmpgtsw:
10807 case Intrinsic::ppc_altivec_vcmpgtsd:
10808 if (Subtarget.hasP8Altivec())
10813 case Intrinsic::ppc_altivec_vcmpgtub:
10816 case Intrinsic::ppc_altivec_vcmpgtuh:
10819 case Intrinsic::ppc_altivec_vcmpgtuw:
10822 case Intrinsic::ppc_altivec_vcmpgtud:
10823 if (Subtarget.hasP8Altivec())
10828 case Intrinsic::ppc_altivec_vcmpequq_p:
10829 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10830 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10831 if (!Subtarget.isISA3_1())
10833 switch (IntrinsicID) {
10836 case Intrinsic::ppc_altivec_vcmpequq_p:
10839 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10842 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10856 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10860 switch (IntrinsicID) {
10861 case Intrinsic::thread_pointer:
10867 case Intrinsic::ppc_rldimi: {
10868 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
10872 return Op.getOperand(2);
10873 if (
Mask.isAllOnes())
10876 unsigned MB = 0, ME = 0;
10880 if (ME < 63 - SH) {
10883 }
else if (ME > 63 - SH) {
10889 {Op.getOperand(2), Src,
10890 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
10891 DAG.getTargetConstant(MB, dl, MVT::i32)}),
10895 case Intrinsic::ppc_rlwimi: {
10898 return Op.getOperand(2);
10899 if (
Mask.isAllOnes())
10902 unsigned MB = 0, ME = 0;
10906 PPC::RLWIMI, dl, MVT::i32,
10907 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
10908 DAG.getTargetConstant(MB, dl, MVT::i32),
10909 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10913 case Intrinsic::ppc_rlwnm: {
10914 if (
Op.getConstantOperandVal(3) == 0)
10916 unsigned MB = 0, ME = 0;
10921 {Op.getOperand(1), Op.getOperand(2),
10922 DAG.getTargetConstant(MB, dl, MVT::i32),
10923 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10927 case Intrinsic::ppc_mma_disassemble_acc: {
10928 if (Subtarget.isISAFuture()) {
10929 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
10967 case Intrinsic::ppc_vsx_disassemble_pair: {
10970 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10975 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
10986 case Intrinsic::ppc_mma_xxmfacc:
10987 case Intrinsic::ppc_mma_xxmtacc: {
10989 if (!Subtarget.isISAFuture())
11000 case Intrinsic::ppc_unpack_longdouble: {
11001 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11002 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11003 "Argument of long double unpack must be 0 or 1!");
11006 Idx->getValueType(0)));
11009 case Intrinsic::ppc_compare_exp_lt:
11010 case Intrinsic::ppc_compare_exp_gt:
11011 case Intrinsic::ppc_compare_exp_eq:
11012 case Intrinsic::ppc_compare_exp_uo: {
11014 switch (IntrinsicID) {
11015 case Intrinsic::ppc_compare_exp_lt:
11018 case Intrinsic::ppc_compare_exp_gt:
11021 case Intrinsic::ppc_compare_exp_eq:
11024 case Intrinsic::ppc_compare_exp_uo:
11030 PPC::SELECT_CC_I4, dl, MVT::i32,
11031 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11032 Op.getOperand(1), Op.getOperand(2)),
11034 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11035 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11038 case Intrinsic::ppc_test_data_class: {
11039 EVT OpVT =
Op.getOperand(1).getValueType();
11040 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11041 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11045 PPC::SELECT_CC_I4, dl, MVT::i32,
11046 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11049 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11050 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11053 case Intrinsic::ppc_fnmsub: {
11054 EVT VT =
Op.getOperand(1).getValueType();
11055 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11061 Op.getOperand(2),
Op.getOperand(3));
11063 case Intrinsic::ppc_convert_f128_to_ppcf128:
11064 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11065 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11066 ? RTLIB::CONVERT_PPCF128_F128
11067 : RTLIB::CONVERT_F128_PPCF128;
11068 MakeLibCallOptions CallOptions;
11069 std::pair<SDValue, SDValue>
Result =
11070 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11074 case Intrinsic::ppc_maxfe:
11075 case Intrinsic::ppc_maxfl:
11076 case Intrinsic::ppc_maxfs:
11077 case Intrinsic::ppc_minfe:
11078 case Intrinsic::ppc_minfl:
11079 case Intrinsic::ppc_minfs: {
11080 EVT VT =
Op.getValueType();
11083 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11084 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11087 if (IntrinsicID == Intrinsic::ppc_minfe ||
11088 IntrinsicID == Intrinsic::ppc_minfl ||
11089 IntrinsicID == Intrinsic::ppc_minfs)
11111 Op.getOperand(1),
Op.getOperand(2),
11122 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11134 switch (
Op.getConstantOperandVal(1)) {
11137 BitNo = 0; InvertBit =
false;
11140 BitNo = 0; InvertBit =
true;
11143 BitNo = 2; InvertBit =
false;
11146 BitNo = 2; InvertBit =
true;
11168 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11170 switch (
Op.getConstantOperandVal(ArgStart)) {
11171 case Intrinsic::ppc_cfence: {
11172 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11173 SDValue Val =
Op.getOperand(ArgStart + 1);
11175 if (Ty == MVT::i128) {
11180 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11181 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11205 int VectorIndex = 0;
11218 "Expecting an atomic compare-and-swap here.");
11220 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11221 EVT MemVT = AtomicNode->getMemoryVT();
11239 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11240 Ops.
push_back(AtomicNode->getOperand(i));
11252 EVT MemVT =
N->getMemoryVT();
11254 "Expect quadword atomic operations");
11256 unsigned Opc =
N->getOpcode();
11264 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11265 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11268 Ops, MemVT,
N->getMemOperand());
11275 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11285 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11295 N->getMemOperand());
11307 enum DataClassMask {
11309 DC_NEG_INF = 1 << 4,
11310 DC_POS_INF = 1 << 5,
11311 DC_NEG_ZERO = 1 << 2,
11312 DC_POS_ZERO = 1 << 3,
11313 DC_NEG_SUBNORM = 1,
11314 DC_POS_SUBNORM = 1 << 1,
11317 EVT VT =
Op.getValueType();
11319 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11320 : VT == MVT::f64 ? PPC::XSTSTDCDP
11331 return DAG.
getNOT(Dl, Rev, MVT::i1);
11338 TestOp, Dl, MVT::i32,
11340 DC_NEG_ZERO | DC_POS_ZERO |
11341 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11347 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11353 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11358 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11371 bool IsQuiet = Mask &
fcQNan;
11377 if (VT == MVT::f128) {
11381 QuietMask = 0x8000;
11382 }
else if (VT == MVT::f64) {
11394 QuietMask = 0x80000;
11395 }
else if (VT == MVT::f32) {
11397 QuietMask = 0x400000;
11413 unsigned NativeMask = 0;
11415 NativeMask |= DC_NAN;
11417 NativeMask |= DC_NEG_INF;
11419 NativeMask |= DC_POS_INF;
11421 NativeMask |= DC_NEG_ZERO;
11423 NativeMask |= DC_POS_ZERO;
11425 NativeMask |= DC_NEG_SUBNORM;
11427 NativeMask |= DC_POS_SUBNORM;
11430 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11432 TestOp, Dl, MVT::i32,
11441 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11443 uint64_t RHSC =
Op.getConstantOperandVal(1);
11468 "Should only be called for ISD::INSERT_VECTOR_ELT");
11472 EVT VT =
Op.getValueType();
11477 if (VT == MVT::v2f64 &&
C)
11480 if (Subtarget.hasP9Vector()) {
11489 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11490 (isa<LoadSDNode>(V2))) {
11495 BitcastLoad,
Op.getOperand(2));
11496 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11500 if (Subtarget.isISA3_1()) {
11501 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11505 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11506 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11516 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11519 unsigned InsertAtElement =
C->getZExtValue();
11520 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11522 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11536 EVT VT =
Op.getValueType();
11538 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11544 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11545 "Type unsupported without MMA");
11546 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11547 "Type unsupported without paired vector support");
11552 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11554 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11564 std::reverse(Loads.
begin(), Loads.
end());
11565 std::reverse(LoadChains.
begin(), LoadChains.
end());
11583 EVT StoreVT =
Value.getValueType();
11585 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11591 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11592 "Type unsupported without MMA");
11593 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11594 "Type unsupported without paired vector support");
11597 unsigned NumVecs = 2;
11598 if (StoreVT == MVT::v512i1) {
11599 if (Subtarget.isISAFuture()) {
11600 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11602 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11605 Value2 =
SDValue(ExtNode, 1);
11610 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11613 if (Subtarget.isISAFuture()) {
11623 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11637 if (
Op.getValueType() == MVT::v4i32) {
11654 LHS, RHS, DAG, dl, MVT::v4i32);
11657 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11662 }
else if (
Op.getValueType() == MVT::v16i8) {
11668 LHS, RHS, DAG, dl, MVT::v8i16);
11673 LHS, RHS, DAG, dl, MVT::v8i16);
11681 for (
unsigned i = 0; i != 8; ++i) {
11682 if (isLittleEndian) {
11684 Ops[i*2+1] = 2*i+16;
11687 Ops[i*2+1] = 2*i+1+16;
11690 if (isLittleEndian)
11700 bool IsStrict =
Op->isStrictFPOpcode();
11701 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11702 !Subtarget.hasP9Vector())
11712 "Should only be called for ISD::FP_EXTEND");
11716 if (
Op.getValueType() != MVT::v2f64 ||
11717 Op.getOperand(0).getValueType() != MVT::v2f32)
11729 "Node should have 2 operands with second one being a constant!");
11741 int DWord =
Idx >> 1;
11764 LD->getMemoryVT(),
LD->getMemOperand());
11777 LD->getMemoryVT(),
LD->getMemOperand());
11788 switch (
Op.getOpcode()) {
11817 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11843 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11844 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11856 return LowerFP_ROUND(
Op, DAG);
11869 return LowerINTRINSIC_VOID(
Op, DAG);
11871 return LowerBSWAP(
Op, DAG);
11873 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11875 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11877 return LowerIS_FPCLASS(
Op, DAG);
11885 switch (
N->getOpcode()) {
11887 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11904 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
11907 assert(
N->getValueType(0) == MVT::i1 &&
11908 "Unexpected result type for CTR decrement intrinsic");
11910 N->getValueType(0));
11920 switch (
N->getConstantOperandVal(0)) {
11921 case Intrinsic::ppc_pack_longdouble:
11923 N->getOperand(2),
N->getOperand(1)));
11925 case Intrinsic::ppc_maxfe:
11926 case Intrinsic::ppc_minfe:
11927 case Intrinsic::ppc_fnmsub:
11928 case Intrinsic::ppc_convert_f128_to_ppcf128:
11938 EVT VT =
N->getValueType(0);
11940 if (VT == MVT::i64) {
11953 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11957 Results.push_back(LoweredValue);
11958 if (
N->isStrictFPOpcode())
11963 if (!
N->getValueType(0).isVector())
12014 if (isa<LoadInst>(Inst))
12018 Intrinsic::ppc_cfence, {Inst->getType()}),
12028 unsigned AtomicSize,
12029 unsigned BinOpcode,
12030 unsigned CmpOpcode,
12031 unsigned CmpPred)
const {
12035 auto LoadMnemonic = PPC::LDARX;
12036 auto StoreMnemonic = PPC::STDCX;
12037 switch (AtomicSize) {
12041 LoadMnemonic = PPC::LBARX;
12042 StoreMnemonic = PPC::STBCX;
12043 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12046 LoadMnemonic = PPC::LHARX;
12047 StoreMnemonic = PPC::STHCX;
12048 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12051 LoadMnemonic = PPC::LWARX;
12052 StoreMnemonic = PPC::STWCX;
12055 LoadMnemonic = PPC::LDARX;
12056 StoreMnemonic = PPC::STDCX;
12072 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12074 F->insert(It, loopMBB);
12076 F->insert(It, loop2MBB);
12077 F->insert(It, exitMBB);
12083 Register TmpReg = (!BinOpcode) ? incr :
12085 : &PPC::GPRCRegClass);
12110 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12117 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12119 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12147 switch(
MI.getOpcode()) {
12151 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12152 &
MI.getMF()->getRegInfo());
12176 case PPC::EXTSB8_32_64:
12177 case PPC::EXTSB8_rec:
12178 case PPC::EXTSB_rec:
12181 case PPC::EXTSH8_32_64:
12182 case PPC::EXTSH8_rec:
12183 case PPC::EXTSH_rec:
12185 case PPC::EXTSWSLI:
12186 case PPC::EXTSWSLI_32_64:
12187 case PPC::EXTSWSLI_32_64_rec:
12188 case PPC::EXTSWSLI_rec:
12189 case PPC::EXTSW_32:
12190 case PPC::EXTSW_32_64:
12191 case PPC::EXTSW_32_64_rec:
12192 case PPC::EXTSW_rec:
12195 case PPC::SRAWI_rec:
12196 case PPC::SRAW_rec:
12205 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12215 bool IsSignExtended =
12218 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12220 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12221 .
addReg(
MI.getOperand(3).getReg());
12222 MI.getOperand(3).setReg(ValueReg);
12226 if (Subtarget.hasPartwordAtomics())
12234 bool is64bit = Subtarget.
isPPC64();
12236 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12247 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12249 F->insert(It, loopMBB);
12251 F->insert(It, loop2MBB);
12252 F->insert(It, exitMBB);
12258 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12303 if (ptrA != ZeroReg) {
12305 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12313 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12314 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12317 .
addImm(is8bit ? 28 : 27);
12318 if (!isLittleEndian)
12319 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12321 .
addImm(is8bit ? 24 : 16);
12323 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12328 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12338 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12342 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12347 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12351 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12354 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12366 unsigned ValueReg = SReg;
12367 unsigned CmpReg = Incr2Reg;
12368 if (CmpOpcode == PPC::CMPW) {
12370 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12374 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12376 ValueReg = ValueSReg;
12408 .
addImm(is8bit ? 24 : 16)
12429 Register DstReg =
MI.getOperand(0).getReg();
12431 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12432 Register mainDstReg =
MRI.createVirtualRegister(RC);
12433 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12436 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12437 "Invalid Pointer Size!");
12485 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12486 Register BufReg =
MI.getOperand(1).getReg();
12501 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12503 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12506 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12529 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12550 TII->get(PPC::PHI), DstReg)
12554 MI.eraseFromParent();
12568 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12569 "Invalid Pointer Size!");
12572 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12575 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12576 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12590 Register BufReg =
MI.getOperand(0).getReg();
12595 if (PVT == MVT::i64) {
12607 if (PVT == MVT::i64) {
12619 if (PVT == MVT::i64) {
12631 if (PVT == MVT::i64) {
12643 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12653 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12656 MI.eraseFromParent();
12672 "Unexpected stack alignment");
12676 unsigned StackProbeSize =
12679 StackProbeSize &= ~(StackAlign - 1);
12680 return StackProbeSize ? StackProbeSize : StackAlign;
12692 const bool isPPC64 = Subtarget.
isPPC64();
12724 MF->
insert(MBBIter, TestMBB);
12725 MF->
insert(MBBIter, BlockMBB);
12726 MF->
insert(MBBIter, TailMBB);
12731 Register DstReg =
MI.getOperand(0).getReg();
12732 Register NegSizeReg =
MI.getOperand(1).getReg();
12733 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12734 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12735 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12736 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12742 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12744 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12750 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12751 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12753 .
addDef(ActualNegSizeReg)
12755 .
add(
MI.getOperand(2))
12756 .
add(
MI.getOperand(3));
12762 .
addReg(ActualNegSizeReg);
12765 int64_t NegProbeSize = -(int64_t)ProbeSize;
12766 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
12767 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12768 if (!isInt<16>(NegProbeSize)) {
12769 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12771 .
addImm(NegProbeSize >> 16);
12775 .
addImm(NegProbeSize & 0xFFFF);
12782 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12784 .
addReg(ActualNegSizeReg)
12786 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12790 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12793 .
addReg(ActualNegSizeReg);
12802 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12803 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12817 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12828 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12830 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12831 MaxCallFrameSizeReg)
12832 .
add(
MI.getOperand(2))
12833 .
add(
MI.getOperand(3));
12834 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12836 .
addReg(MaxCallFrameSizeReg);
12845 MI.eraseFromParent();
12847 ++NumDynamicAllocaProbed;
12852 switch (
MI.getOpcode()) {
12853 case PPC::SELECT_CC_I4:
12854 case PPC::SELECT_CC_I8:
12855 case PPC::SELECT_CC_F4:
12856 case PPC::SELECT_CC_F8:
12857 case PPC::SELECT_CC_F16:
12858 case PPC::SELECT_CC_VRRC:
12859 case PPC::SELECT_CC_VSFRC:
12860 case PPC::SELECT_CC_VSSRC:
12861 case PPC::SELECT_CC_VSRC:
12862 case PPC::SELECT_CC_SPE4:
12863 case PPC::SELECT_CC_SPE:
12871 switch (
MI.getOpcode()) {
12872 case PPC::SELECT_I4:
12873 case PPC::SELECT_I8:
12874 case PPC::SELECT_F4:
12875 case PPC::SELECT_F8:
12876 case PPC::SELECT_F16:
12877 case PPC::SELECT_SPE:
12878 case PPC::SELECT_SPE4:
12879 case PPC::SELECT_VRRC:
12880 case PPC::SELECT_VSFRC:
12881 case PPC::SELECT_VSSRC:
12882 case PPC::SELECT_VSRC:
12892 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12893 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12895 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12908 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12909 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12911 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12912 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12926 if (Subtarget.hasISEL() &&
12927 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12928 MI.getOpcode() == PPC::SELECT_CC_I8 ||
12929 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
12931 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12932 MI.getOpcode() == PPC::SELECT_CC_I8)
12933 Cond.push_back(
MI.getOperand(4));
12936 Cond.push_back(
MI.getOperand(1));
12939 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12940 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12956 F->insert(It, copy0MBB);
12957 F->insert(It, sinkMBB);
12961 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
12976 .
addReg(
MI.getOperand(1).getReg())
12979 unsigned SelectPred =
MI.getOperand(4).getImm();
12982 .
addReg(
MI.getOperand(1).getReg())
12999 .
addReg(
MI.getOperand(3).getReg())
13001 .
addReg(
MI.getOperand(2).getReg())
13003 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13019 F->insert(It, readMBB);
13020 F->insert(It, sinkMBB);
13041 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13051 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13053 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13055 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13057 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13060 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13062 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13064 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13066 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13069 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13071 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13073 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13075 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13078 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13080 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13082 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13084 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13087 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13089 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13091 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13093 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13096 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13098 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13100 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13102 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13105 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13107 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13109 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13111 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13114 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13116 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13118 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13120 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13123 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13125 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13127 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13129 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13132 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13134 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13136 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13138 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13141 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13143 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13145 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13147 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13149 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13150 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13151 (Subtarget.hasPartwordAtomics() &&
13152 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13153 (Subtarget.hasPartwordAtomics() &&
13154 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13155 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13157 auto LoadMnemonic = PPC::LDARX;
13158 auto StoreMnemonic = PPC::STDCX;
13159 switch (
MI.getOpcode()) {
13162 case PPC::ATOMIC_CMP_SWAP_I8:
13163 LoadMnemonic = PPC::LBARX;
13164 StoreMnemonic = PPC::STBCX;
13165 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13167 case PPC::ATOMIC_CMP_SWAP_I16:
13168 LoadMnemonic = PPC::LHARX;
13169 StoreMnemonic = PPC::STHCX;
13170 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13172 case PPC::ATOMIC_CMP_SWAP_I32:
13173 LoadMnemonic = PPC::LWARX;
13174 StoreMnemonic = PPC::STWCX;
13176 case PPC::ATOMIC_CMP_SWAP_I64:
13177 LoadMnemonic = PPC::LDARX;
13178 StoreMnemonic = PPC::STDCX;
13186 Register oldval =
MI.getOperand(3).getReg();
13187 Register newval =
MI.getOperand(4).getReg();
13193 F->insert(It, loop1MBB);
13194 F->insert(It, loop2MBB);
13195 F->insert(It, exitMBB);
13216 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13242 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13243 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13247 bool is64bit = Subtarget.
isPPC64();
13249 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13254 Register oldval =
MI.getOperand(3).getReg();
13255 Register newval =
MI.getOperand(4).getReg();
13261 F->insert(It, loop1MBB);
13262 F->insert(It, loop2MBB);
13263 F->insert(It, exitMBB);
13270 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13289 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13321 if (ptrA != ZeroReg) {
13323 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13332 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13333 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13336 .
addImm(is8bit ? 28 : 27);
13337 if (!isLittleEndian)
13338 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13340 .
addImm(is8bit ? 24 : 16);
13342 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13347 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13352 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13355 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13362 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13366 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13369 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13372 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13377 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13394 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13418 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13443 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13451 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13452 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13453 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13454 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13455 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13456 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13459 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13460 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13464 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13468 .
addReg(
MI.getOperand(1).getReg())
13471 MI.getOperand(0).getReg())
13472 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13473 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13479 MI.getOperand(0).getReg())
13481 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13483 unsigned Imm =
MI.getOperand(1).getImm();
13486 MI.getOperand(0).getReg())
13488 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13490 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13493 if (
MRI.use_empty(OldFPSCRReg))
13494 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13496 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13507 unsigned Mode =
MI.getOperand(1).getImm();
13508 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13512 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13515 }
else if (
MI.getOpcode() == PPC::SETRND) {
13523 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13524 if (Subtarget.hasDirectMove()) {
13525 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13529 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13532 if (RC == &PPC::F8RCRegClass) {
13535 "Unsupported RegClass.");
13537 StoreOp = PPC::STFD;
13542 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13543 "Unsupported RegClass.");
13576 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13579 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13593 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13601 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13602 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13608 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13615 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13624 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13628 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13629 if (
MRI.use_empty(OldFPSCRReg))
13630 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13632 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13635 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13641 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13642 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13644 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13651 .
addUse(Src, 0, PPC::sub_gp8_x1);
13654 .
addUse(Src, 0, PPC::sub_gp8_x0);
13655 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13656 MI.getOpcode() == PPC::STQX_PSEUDO) {
13662 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13668 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13669 :
TII->get(PPC::STQ))
13677 MI.eraseFromParent();
13690 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13693 return RefinementSteps;
13699 EVT VT =
Op.getValueType();
13702 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13726PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13729 EVT VT =
Op.getValueType();
13730 if (VT != MVT::f64 &&
13731 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13738 int Enabled,
int &RefinementSteps,
13739 bool &UseOneConstNR,
13740 bool Reciprocal)
const {
13742 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13743 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13744 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13745 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13751 UseOneConstNR = !Subtarget.needsTwoConstNR();
13759 int &RefinementSteps)
const {
13761 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13762 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13763 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13764 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13772unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13810 unsigned Bytes,
int Dist,
13820 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13821 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13824 if (FS != BFS || FS != (
int)Bytes)
return false;
13828 SDValue Base1 = Loc, Base2 = BaseLoc;
13829 int64_t Offset1 = 0, Offset2 = 0;
13832 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13842 if (isGA1 && isGA2 && GV1 == GV2)
13843 return Offset1 == (Offset2 + Dist*Bytes);
13850 unsigned Bytes,
int Dist,
13853 EVT VT = LS->getMemoryVT();
13854 SDValue Loc = LS->getBasePtr();
13860 switch (
N->getConstantOperandVal(1)) {
13861 default:
return false;
13862 case Intrinsic::ppc_altivec_lvx:
13863 case Intrinsic::ppc_altivec_lvxl:
13864 case Intrinsic::ppc_vsx_lxvw4x:
13865 case Intrinsic::ppc_vsx_lxvw4x_be:
13868 case Intrinsic::ppc_vsx_lxvd2x:
13869 case Intrinsic::ppc_vsx_lxvd2x_be:
13872 case Intrinsic::ppc_altivec_lvebx:
13875 case Intrinsic::ppc_altivec_lvehx:
13878 case Intrinsic::ppc_altivec_lvewx:
13888 switch (
N->getConstantOperandVal(1)) {
13889 default:
return false;
13890 case Intrinsic::ppc_altivec_stvx:
13891 case Intrinsic::ppc_altivec_stvxl:
13892 case Intrinsic::ppc_vsx_stxvw4x:
13895 case Intrinsic::ppc_vsx_stxvd2x:
13898 case Intrinsic::ppc_vsx_stxvw4x_be:
13901 case Intrinsic::ppc_vsx_stxvd2x_be:
13904 case Intrinsic::ppc_altivec_stvebx:
13907 case Intrinsic::ppc_altivec_stvehx:
13910 case Intrinsic::ppc_altivec_stvewx:
13927 SDValue Chain = LD->getChain();
13928 EVT VT = LD->getMemoryVT();
13937 while (!Queue.empty()) {
13938 SDNode *ChainNext = Queue.pop_back_val();
13939 if (!Visited.
insert(ChainNext).second)
13942 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
13946 if (!Visited.
count(ChainLD->getChain().getNode()))
13947 Queue.push_back(ChainLD->getChain().getNode());
13949 for (
const SDUse &O : ChainNext->
ops())
13950 if (!Visited.
count(O.getNode()))
13951 Queue.push_back(O.getNode());
13953 LoadRoots.
insert(ChainNext);
13964 for (
SDNode *
I : LoadRoots) {
13965 Queue.push_back(
I);
13967 while (!Queue.empty()) {
13968 SDNode *LoadRoot = Queue.pop_back_val();
13969 if (!Visited.
insert(LoadRoot).second)
13972 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
13977 if (((isa<MemSDNode>(U) &&
13978 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
13981 Queue.push_back(U);
14014 auto Final = Shifted;
14025 DAGCombinerInfo &DCI)
const {
14033 if (!DCI.isAfterLegalizeDAG())
14038 for (
const SDNode *U :
N->uses())
14043 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14047 if (OpSize <
Size) {
14065 DAGCombinerInfo &DCI)
const {
14069 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14080 N->getValueType(0) != MVT::i1)
14083 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14084 N->getOperand(0).getValueType() != MVT::i64)
14092 cast<CondCodeSDNode>(
N->getOperand(
14094 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14105 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14128 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14129 N->getOperand(0).getOpcode() !=
ISD::OR &&
14130 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14140 N->getOperand(1).getOpcode() !=
ISD::AND &&
14141 N->getOperand(1).getOpcode() !=
ISD::OR &&
14142 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14155 for (
unsigned i = 0; i < 2; ++i) {
14159 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14160 isa<ConstantSDNode>(
N->getOperand(i)))
14171 while (!BinOps.
empty()) {
14179 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14213 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14214 if (isa<ConstantSDNode>(Inputs[i]))
14237 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14259 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14262 if (isa<ConstantSDNode>(Inputs[i]))
14268 std::list<HandleSDNode> PromOpHandles;
14269 for (
auto &PromOp : PromOps)
14270 PromOpHandles.emplace_back(PromOp);
14277 while (!PromOpHandles.empty()) {
14279 PromOpHandles.pop_back();
14285 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14288 PromOpHandles.emplace_front(PromOp);
14293 if (isa<ConstantSDNode>(RepValue))
14302 default:
C = 0;
break;
14307 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14315 PromOpHandles.emplace_front(PromOp);
14323 for (
unsigned i = 0; i < 2; ++i)
14324 if (isa<ConstantSDNode>(Ops[
C+i]))
14333 return N->getOperand(0);
14341 DAGCombinerInfo &DCI)
const {
14359 if (
N->getValueType(0) != MVT::i32 &&
14360 N->getValueType(0) != MVT::i64)
14363 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14364 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14367 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14368 N->getOperand(0).getOpcode() !=
ISD::OR &&
14369 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14380 while (!BinOps.
empty()) {
14388 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14419 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14420 if (isa<ConstantSDNode>(Inputs[i]))
14431 SelectTruncOp[0].
insert(std::make_pair(
User,
14435 SelectTruncOp[0].
insert(std::make_pair(
User,
14438 SelectTruncOp[1].
insert(std::make_pair(
User,
14444 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14453 SelectTruncOp[0].
insert(std::make_pair(
User,
14457 SelectTruncOp[0].
insert(std::make_pair(
User,
14460 SelectTruncOp[1].
insert(std::make_pair(
User,
14466 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14467 bool ReallyNeedsExt =
false;
14471 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14472 if (isa<ConstantSDNode>(Inputs[i]))
14476 Inputs[i].getOperand(0).getValueSizeInBits();
14477 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14482 OpBits-PromBits))) ||
14485 (OpBits-(PromBits-1)))) {
14486 ReallyNeedsExt =
true;
14494 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14498 if (isa<ConstantSDNode>(Inputs[i]))
14501 SDValue InSrc = Inputs[i].getOperand(0);
14515 std::list<HandleSDNode> PromOpHandles;
14516 for (
auto &PromOp : PromOps)
14517 PromOpHandles.emplace_back(PromOp);
14523 while (!PromOpHandles.empty()) {
14525 PromOpHandles.pop_back();
14529 default:
C = 0;
break;
14534 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14542 PromOpHandles.emplace_front(PromOp);
14552 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14554 PromOpHandles.emplace_front(PromOp);
14563 for (
unsigned i = 0; i < 2; ++i) {
14564 if (!isa<ConstantSDNode>(Ops[
C+i]))
14581 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14582 if (SI0 != SelectTruncOp[0].
end())
14584 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14585 if (SI1 != SelectTruncOp[1].
end())
14594 if (!ReallyNeedsExt)
14595 return N->getOperand(0);
14602 N->getValueSizeInBits(0), PromBits),
14603 dl,
N->getValueType(0)));
14606 "Invalid extension type");
14609 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14617 DAGCombinerInfo &DCI)
const {
14619 "Should be called with a SETCC node");
14637 EVT VT =
N->getValueType(0);
14638 EVT OpVT =
LHS.getValueType();
14644 return DAGCombineTruncBoolExt(
N, DCI);
14649 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14651 Op.getValueType() == MVT::f64;
14663combineElementTruncationToVectorTruncation(
SDNode *
N,
14664 DAGCombinerInfo &DCI)
const {
14666 "Should be called with a BUILD_VECTOR node");
14671 SDValue FirstInput =
N->getOperand(0);
14673 "The input operand must be an fp-to-int conversion.");
14682 bool IsSplat =
true;
14687 EVT TargetVT =
N->getValueType(0);
14688 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14689 SDValue NextOp =
N->getOperand(i);
14693 if (NextConversion != FirstConversion)
14701 if (
N->getOperand(i) != FirstInput)
14712 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14713 SDValue In =
N->getOperand(i).getOperand(0);
14736 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14738 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14751 "Should be called with a BUILD_VECTOR node");
14756 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14759 bool InputsAreConsecutiveLoads =
true;
14760 bool InputsAreReverseConsecutive =
true;
14761 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14762 SDValue FirstInput =
N->getOperand(0);
14763 bool IsRoundOfExtLoad =
false;
14768 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
14773 N->getNumOperands() == 1)
14776 if (!IsRoundOfExtLoad)
14777 FirstLoad = cast<LoadSDNode>(FirstInput);
14781 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14783 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14786 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14792 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14793 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
14794 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
14803 InputsAreConsecutiveLoads =
false;
14805 InputsAreReverseConsecutive =
false;
14808 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14813 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14814 "The loads cannot be both consecutive and reverse consecutive.");
14818 if (InputsAreConsecutiveLoads) {
14819 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14823 ReturnSDVal = WideLoad;
14824 }
else if (InputsAreReverseConsecutive) {
14826 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14831 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14835 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14839 for (
auto *LD : InputLoads)
14841 return ReturnSDVal;
14858 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14860 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14862 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14863 CorrectElems = CorrectElems >> 8;
14864 Elems = Elems >> 8;
14871 EVT VT =
N->getValueType(0);
14909 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14929 if (Input && Input != Extract.
getOperand(0))
14935 Elems = Elems << 8;
14944 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14945 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14952 int TgtElemArrayIdx;
14954 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14955 if (InputSize + OutputSize == 40)
14956 TgtElemArrayIdx = 0;
14957 else if (InputSize + OutputSize == 72)
14958 TgtElemArrayIdx = 1;
14959 else if (InputSize + OutputSize == 48)
14960 TgtElemArrayIdx = 2;
14961 else if (InputSize + OutputSize == 80)
14962 TgtElemArrayIdx = 3;
14963 else if (InputSize + OutputSize == 96)
14964 TgtElemArrayIdx = 4;
14968 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14970 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14971 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14972 if (Elems != CorrectElems) {
14988 if (
N->getValueType(0) != MVT::v1i128)
14991 SDValue Operand =
N->getOperand(0);
14997 auto *LD = cast<LoadSDNode>(Operand);
14998 EVT MemoryType = LD->getMemoryVT();
15002 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15003 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15006 if (!ValidLDType ||
15012 LD->getChain(), LD->getBasePtr(),
15016 DAG.
getVTList(MVT::v1i128, MVT::Other),
15017 LoadOps, MemoryType, LD->getMemOperand());
15021 DAGCombinerInfo &DCI)
const {
15023 "Should be called with a BUILD_VECTOR node");
15028 if (!Subtarget.hasVSX())
15034 SDValue FirstInput =
N->getOperand(0);
15036 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15051 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15060 if (Subtarget.isISA3_1()) {
15066 if (
N->getValueType(0) != MVT::v2f64)
15077 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15081 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15088 if (!Ext1Op || !Ext2Op)
15097 if (FirstElem == 0 && SecondElem == 1)
15099 else if (FirstElem == 2 && SecondElem == 3)
15107 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15112 DAGCombinerInfo &DCI)
const {
15115 "Need an int -> FP conversion node here");
15126 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15128 if (!
Op.getOperand(0).getValueType().isSimple())
15130 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15131 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15134 SDValue FirstOperand(
Op.getOperand(0));
15135 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15136 (FirstOperand.getValueType() == MVT::i8 ||
15137 FirstOperand.getValueType() == MVT::i16);
15138 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15140 bool DstDouble =
Op.getValueType() == MVT::f64;
15141 unsigned ConvOp =
Signed ?
15147 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15156 SDValue ExtOps[] = { Ld, WidthConst };
15158 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15160 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15168 if (
Op.getOperand(0).getValueType() == MVT::i32)
15172 "UINT_TO_FP is supported only with FPCVT");
15176 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15181 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15188 Subtarget.hasFPCVT()) ||
15190 SDValue Src =
Op.getOperand(0).getOperand(0);
15191 if (Src.getValueType() == MVT::f32) {
15193 DCI.AddToWorklist(Src.getNode());
15194 }
else if (Src.getValueType() != MVT::f64) {
15206 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15209 DCI.AddToWorklist(
FP.getNode());
15233 switch (
N->getOpcode()) {
15238 Chain = LD->getChain();
15239 Base = LD->getBasePtr();
15240 MMO = LD->getMemOperand();
15259 MVT VecTy =
N->getValueType(0).getSimpleVT();
15267 Chain = Load.getValue(1);
15273 if (VecTy != MVT::v2f64) {
15300 switch (
N->getOpcode()) {
15305 Chain = ST->getChain();
15306 Base = ST->getBasePtr();
15307 MMO = ST->getMemOperand();
15327 SDValue Src =
N->getOperand(SrcOpnd);
15328 MVT VecTy = Src.getValueType().getSimpleVT();
15331 if (VecTy != MVT::v2f64) {
15337 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15343 StoreOps, VecTy, MMO);
15350 DAGCombinerInfo &DCI)
const {
15353 unsigned Opcode =
N->getOperand(1).getOpcode();
15355 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15359 &&
"Not a FP_TO_INT Instruction!");
15361 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15362 EVT Op1VT =
N->getOperand(1).getValueType();
15365 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15369 bool ValidTypeForStoreFltAsInt =
15370 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15371 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15374 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15377 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15378 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15385 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15391 cast<StoreSDNode>(
N)->getMemoryVT(),
15392 cast<StoreSDNode>(
N)->getMemOperand());
15400 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15401 for (
int i = 1, e = Mask.size(); i < e; i++) {
15402 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15404 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15406 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15418 FirstOp =
Op.getOperand(i);
15425 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15435 Op =
Op.getOperand(0);
15450 int LHSMaxIdx,
int RHSMinIdx,
15451 int RHSMaxIdx,
int HalfVec,
15452 unsigned ValidLaneWidth,
15454 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15455 int Idx = ShuffV[i];
15456 if ((
Idx >= 0 &&
Idx < LHSMaxIdx) || (
Idx >= RHSMinIdx &&
Idx < RHSMaxIdx))
15458 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15469 SDLoc dl(OrigSToV);
15472 "Expecting a SCALAR_TO_VECTOR here");
15485 "Cannot produce a permuted scalar_to_vector for one element vector");
15487 unsigned ResultInElt = NumElts / 2;
15489 NewMask[ResultInElt] =
Idx->getZExtValue();
15514 int NumElts =
LHS.getValueType().getVectorNumElements();
15524 if (!Subtarget.hasDirectMove())
15534 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15543 if (SToVLHS || SToVRHS) {
15550 if (SToVLHS && SToVRHS &&
15557 int NumEltsOut = ShuffV.
size();
15562 unsigned ValidLaneWidth =
15564 LHS.getValueType().getScalarSizeInBits()
15566 RHS.getValueType().getScalarSizeInBits();
15570 int LHSMaxIdx = -1;
15571 int RHSMinIdx = -1;
15572 int RHSMaxIdx = -1;
15573 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
15585 LHSMaxIdx = NumEltsOut / NumEltsIn;
15594 RHSMinIdx = NumEltsOut;
15595 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15608 HalfVec, ValidLaneWidth, Subtarget);
15613 if (!isa<ShuffleVectorSDNode>(Res))
15615 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15634 if (IsLittleEndian) {
15637 if (Mask[0] < NumElts)
15638 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15642 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15647 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15651 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15656 if (Mask[0] < NumElts)
15657 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15661 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15666 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
15670 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15677 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
15680 if (IsLittleEndian)
15689 DAGCombinerInfo &DCI)
const {
15691 "Not a reverse memop pattern!");
15696 auto I =
Mask.rbegin();
15697 auto E =
Mask.rend();
15699 for (;
I != E; ++
I) {
15716 if (!Subtarget.hasP9Vector())
15719 if(!IsElementReverse(SVN))
15758 if (IntrinsicID == Intrinsic::ppc_stdcx)
15760 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15762 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15764 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15775 switch (
N->getOpcode()) {
15778 return combineADD(
N, DCI);
15787 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
15797 if (!isUInt<32>(Imm))
15804 return combineSHL(
N, DCI);
15806 return combineSRA(
N, DCI);
15808 return combineSRL(
N, DCI);
15810 return combineMUL(
N, DCI);
15813 return combineFMALike(
N, DCI);
15816 return N->getOperand(0);
15820 return N->getOperand(0);
15826 return N->getOperand(0);
15832 return DAGCombineExtBoolTrunc(
N, DCI);
15834 return combineTRUNCATE(
N, DCI);
15836 if (
SDValue CSCC = combineSetCC(
N, DCI))
15840 return DAGCombineTruncBoolExt(
N, DCI);
15843 return combineFPToIntToFP(
N, DCI);
15846 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15847 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15849 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15852 EVT Op1VT =
N->getOperand(1).getValueType();
15853 unsigned Opcode =
N->getOperand(1).getOpcode();
15857 SDValue Val = combineStoreFPToInt(
N, DCI);
15864 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15870 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15871 N->getOperand(1).getNode()->hasOneUse() &&
15872 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15873 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15877 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15881 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15888 if (Op1VT.
bitsGT(mVT)) {
15893 if (Op1VT == MVT::i64)
15898 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15902 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15903 cast<StoreSDNode>(
N)->getMemOperand());
15909 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
15911 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15921 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15930 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15931 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
15938 EVT VT = LD->getValueType(0);
15945 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
15946 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
15957 auto ReplaceTwoFloatLoad = [&]() {
15958 if (VT != MVT::i64)
15973 if (!LD->hasNUsesOfValue(2, 0))
15976 auto UI = LD->use_begin();
15977 while (UI.getUse().getResNo() != 0) ++UI;
15979 while (UI.getUse().getResNo() != 0) ++UI;
15980 SDNode *RightShift = *UI;
15988 if (RightShift->getOpcode() !=
ISD::SRL ||
15989 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
15990 RightShift->getConstantOperandVal(1) != 32 ||
15991 !RightShift->hasOneUse())
15994 SDNode *Trunc2 = *RightShift->use_begin();
16004 Bitcast->getValueType(0) != MVT::f32)
16016 SDValue BasePtr = LD->getBasePtr();
16017 if (LD->isIndexed()) {
16019 "Non-pre-inc AM on PPC?");
16027 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16028 LD->getPointerInfo(), LD->getAlign(),
16029 MMOFlags, LD->getAAInfo());
16035 LD->getPointerInfo().getWithOffset(4),
16038 if (LD->isIndexed()) {
16052 if (ReplaceTwoFloatLoad())
16055 EVT MemVT = LD->getMemoryVT();
16058 if (LD->isUnindexed() && VT.
isVector() &&
16061 !Subtarget.hasP8Vector() &&
16062 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16063 VT == MVT::v4f32))) &&
16064 LD->getAlign() < ABIAlignment) {
16066 SDValue Chain = LD->getChain();
16095 MVT PermCntlTy, PermTy, LDTy;
16096 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16097 : Intrinsic::ppc_altivec_lvsl;
16098 IntrLD = Intrinsic::ppc_altivec_lvx;
16099 IntrPerm = Intrinsic::ppc_altivec_vperm;
16100 PermCntlTy = MVT::v16i8;
16101 PermTy = MVT::v4i32;
16120 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16124 BaseLoadOps, LDTy, BaseMMO);
16133 int IncValue = IncOffset;
16150 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16154 ExtraLoadOps, LDTy, ExtraMMO);
16165 if (isLittleEndian)
16167 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16170 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16173 Perm = Subtarget.hasAltivec()
16189 unsigned IID =
N->getConstantOperandVal(0);
16191 : Intrinsic::ppc_altivec_lvsl);
16192 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16199 .
zext(
Add.getScalarValueSizeInBits()))) {
16200 SDNode *BasePtr =
Add->getOperand(0).getNode();
16201 for (
SDNode *U : BasePtr->uses()) {
16203 U->getConstantOperandVal(0) == IID) {
16213 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16214 SDNode *BasePtr =
Add->getOperand(0).getNode();
16215 for (
SDNode *U : BasePtr->uses()) {
16217 isa<ConstantSDNode>(U->getOperand(1)) &&
16218 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16224 V->getConstantOperandVal(0) == IID) {
16236 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16237 IID == Intrinsic::ppc_altivec_vmaxsh ||
16238 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16254 V2.getOperand(1) == V1) {
16269 switch (
N->getConstantOperandVal(1)) {
16272 case Intrinsic::ppc_altivec_vsum4sbs:
16273 case Intrinsic::ppc_altivec_vsum4shs:
16274 case Intrinsic::ppc_altivec_vsum4ubs: {
16280 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16281 APInt APSplatBits, APSplatUndef;
16282 unsigned SplatBitSize;
16285 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16288 if (BVNIsConstantSplat && APSplatBits == 0)
16293 case Intrinsic::ppc_vsx_lxvw4x:
16294 case Intrinsic::ppc_vsx_lxvd2x:
16306 switch (
N->getConstantOperandVal(1)) {
16309 case Intrinsic::ppc_vsx_stxvw4x:
16310 case Intrinsic::ppc_vsx_stxvd2x:
16319 bool Is64BitBswapOn64BitTgt =
16320 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16322 N->getOperand(0).hasOneUse();
16323 if (IsSingleUseNormalLd &&
16324 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16325 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16336 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16337 MVT::i64 : MVT::i32, MVT::Other),
16338 Ops, LD->getMemoryVT(), LD->getMemOperand());
16342 if (
N->getValueType(0) == MVT::i16)
16359 !IsSingleUseNormalLd)
16361 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16364 if (!LD->isSimple())
16366 SDValue BasePtr = LD->getBasePtr();
16368 LD->getPointerInfo(), LD->getAlign());
16373 LD->getMemOperand(), 4, 4);
16383 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16392 if (!
N->getOperand(0).hasOneUse() &&
16393 !
N->getOperand(1).hasOneUse() &&
16394 !
N->getOperand(2).hasOneUse()) {
16397 SDNode *VCMPrecNode =
nullptr;
16399 SDNode *LHSN =
N->getOperand(0).getNode();
16403 UI->getOperand(1) ==
N->getOperand(1) &&
16404 UI->getOperand(2) ==
N->getOperand(2) &&
16405 UI->getOperand(0) ==
N->getOperand(0)) {
16418 SDNode *FlagUser =
nullptr;
16420 FlagUser ==
nullptr; ++UI) {
16421 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16434 return SDValue(VCMPrecNode, 0);
16456 auto RHSAPInt =
RHS->getAsAPIntVal();
16457 if (!RHSAPInt.isIntN(64))
16460 unsigned Val = RHSAPInt.getZExtValue();
16461 auto isImpossibleCompare = [&]() {
16464 if (Val != 0 && Val != 1) {
16466 return N->getOperand(0);
16469 N->getOperand(0),
N->getOperand(4));
16474 unsigned StoreWidth = 0;
16477 if (
SDValue Impossible = isImpossibleCompare())
16491 auto *MemNode = cast<MemSDNode>(
LHS);
16494 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16495 MemNode->getMemoryVT(), MemNode->getMemOperand());
16499 if (
N->getOperand(0) ==
LHS.getValue(1))
16500 InChain =
LHS.getOperand(0);
16512 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16518 assert(isDot &&
"Can't compare against a vector result!");
16520 if (
SDValue Impossible = isImpossibleCompare())
16523 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16530 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16535 switch (
LHS.getConstantOperandVal(1)) {
16554 N->getOperand(4), CompNode.
getValue(1));
16559 return DAGCombineBuildVector(
N, DCI);
16570 EVT VT =
N->getValueType(0);
16571 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16573 if ((VT != MVT::i32 && VT != MVT::i64) ||
16581 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16601 const APInt &DemandedElts,
16603 unsigned Depth)
const {
16605 switch (
Op.getOpcode()) {
16609 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16610 Known.
Zero = 0xFFFF0000;
16614 switch (
Op.getConstantOperandVal(0)) {
16616 case Intrinsic::ppc_altivec_vcmpbfp_p:
16617 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16618 case Intrinsic::ppc_altivec_vcmpequb_p:
16619 case Intrinsic::ppc_altivec_vcmpequh_p:
16620 case Intrinsic::ppc_altivec_vcmpequw_p:
16621 case Intrinsic::ppc_altivec_vcmpequd_p:
16622 case Intrinsic::ppc_altivec_vcmpequq_p:
16623 case Intrinsic::ppc_altivec_vcmpgefp_p:
16624 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16625 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16626 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16627 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16628 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16629 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16630 case Intrinsic::ppc_altivec_vcmpgtub_p:
16631 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16632 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16633 case Intrinsic::ppc_altivec_vcmpgtud_p:
16634 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16641 switch (
Op.getConstantOperandVal(1)) {
16644 case Intrinsic::ppc_load2r:
16646 Known.
Zero = 0xFFFF0000;
16676 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16685 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16687 LoopSize +=
TII->getInstSizeInBytes(J);
16692 if (LoopSize > 16 && LoopSize <= 32)
16706 if (Constraint.
size() == 1) {
16707 switch (Constraint[0]) {
16725 }
else if (Constraint ==
"wc") {
16727 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16728 Constraint ==
"wf" || Constraint ==
"ws" ||
16729 Constraint ==
"wi" || Constraint ==
"ww") {
16742 Value *CallOperandVal =
info.CallOperandVal;
16745 if (!CallOperandVal)
16752 else if ((
StringRef(constraint) ==
"wa" ||
16764 switch (*constraint) {
16794std::pair<unsigned, const TargetRegisterClass *>
16798 if (Constraint.
size() == 1) {
16800 switch (Constraint[0]) {
16802 if (VT == MVT::i64 && Subtarget.
isPPC64())
16803 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16804 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16806 if (VT == MVT::i64 && Subtarget.
isPPC64())
16807 return std::make_pair(0U, &PPC::G8RCRegClass);
16808 return std::make_pair(0U, &PPC::GPRCRegClass);
16814 if (Subtarget.hasSPE()) {
16815 if (VT == MVT::f32 || VT == MVT::i32)
16816 return std::make_pair(0U, &PPC::GPRCRegClass);
16817 if (VT == MVT::f64 || VT == MVT::i64)
16818 return std::make_pair(0U, &PPC::SPERCRegClass);
16820 if (VT == MVT::f32 || VT == MVT::i32)
16821 return std::make_pair(0U, &PPC::F4RCRegClass);
16822 if (VT == MVT::f64 || VT == MVT::i64)
16823 return std::make_pair(0U, &PPC::F8RCRegClass);
16827 if (Subtarget.hasAltivec() && VT.
isVector())
16828 return std::make_pair(0U, &PPC::VRRCRegClass);
16829 else if (Subtarget.hasVSX())
16831 return std::make_pair(0U, &PPC::VFRCRegClass);
16834 return std::make_pair(0U, &PPC::CRRCRegClass);
16836 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16838 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16839 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16840 Constraint ==
"wf" || Constraint ==
"wi") &&
16841 Subtarget.hasVSX()) {
16845 return std::make_pair(0U, &PPC::VSRCRegClass);
16846 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16847 return std::make_pair(0U, &PPC::VSSRCRegClass);
16848 return std::make_pair(0U, &PPC::VSFRCRegClass);
16849 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16850 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16851 return std::make_pair(0U, &PPC::VSSRCRegClass);
16853 return std::make_pair(0U, &PPC::VSFRCRegClass);
16854 }
else if (Constraint ==
"lr") {
16855 if (VT == MVT::i64)
16856 return std::make_pair(0U, &PPC::LR8RCRegClass);
16858 return std::make_pair(0U, &PPC::LRRCRegClass);
16863 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16867 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16868 int VSNum = atoi(Constraint.
data() + 3);
16869 assert(VSNum >= 0 && VSNum <= 63 &&
16870 "Attempted to access a vsr out of range");
16872 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16873 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16878 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16879 int RegNum = atoi(Constraint.
data() + 2);
16880 if (RegNum > 31 || RegNum < 0)
16882 if (VT == MVT::f32 || VT == MVT::i32)
16883 return Subtarget.hasSPE()
16884 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16885 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16886 if (VT == MVT::f64 || VT == MVT::i64)
16887 return Subtarget.hasSPE()
16888 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16889 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16893 std::pair<unsigned, const TargetRegisterClass *> R =
16902 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16903 PPC::GPRCRegClass.contains(R.first))
16904 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16905 PPC::sub_32, &PPC::G8RCRegClass),
16906 &PPC::G8RCRegClass);
16909 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16910 R.first = PPC::CR0;
16911 R.second = &PPC::CRRCRegClass;
16915 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16916 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16917 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16918 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16919 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16920 "default AIX AltiVec ABI and cannot be used\n";
16930 std::vector<SDValue> &Ops,
16935 if (Constraint.
size() > 1)
16938 char Letter = Constraint[0];
16953 EVT TCVT = MVT::i64;
16958 if (isInt<16>(
Value))
16962 if (isShiftedUInt<16, 16>(
Value))
16966 if (isShiftedInt<16, 16>(
Value))
16970 if (isUInt<16>(
Value))
16986 if (isInt<16>(-
Value))
16994 if (Result.getNode()) {
16995 Ops.push_back(Result);
17006 if (
I.getNumOperands() <= 1)
17008 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17010 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17011 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17012 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17015 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17043 switch (AM.
Scale) {
17074 unsigned Depth =
Op.getConstantOperandVal(0);
17080 bool isPPC64 = Subtarget.
isPPC64();
17092 isPPC64 ? MVT::i64 : MVT::i32);
17099 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17107 unsigned Depth =
Op.getConstantOperandVal(0);
17114 bool isPPC64 = PtrVT == MVT::i64;
17120 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17122 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17136 bool isPPC64 = Subtarget.
isPPC64();
17170 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17188 unsigned Intrinsic)
const {
17189 switch (Intrinsic) {
17190 case Intrinsic::ppc_atomicrmw_xchg_i128:
17191 case Intrinsic::ppc_atomicrmw_add_i128:
17192 case Intrinsic::ppc_atomicrmw_sub_i128:
17193 case Intrinsic::ppc_atomicrmw_nand_i128:
17194 case Intrinsic::ppc_atomicrmw_and_i128:
17195 case Intrinsic::ppc_atomicrmw_or_i128:
17196 case Intrinsic::ppc_atomicrmw_xor_i128:
17197 case Intrinsic::ppc_cmpxchg_i128:
17199 Info.memVT = MVT::i128;
17200 Info.ptrVal =
I.getArgOperand(0);
17206 case Intrinsic::ppc_atomic_load_i128:
17208 Info.memVT = MVT::i128;
17209 Info.ptrVal =
I.getArgOperand(0);
17214 case Intrinsic::ppc_atomic_store_i128:
17216 Info.memVT = MVT::i128;
17217 Info.ptrVal =
I.getArgOperand(2);
17222 case Intrinsic::ppc_altivec_lvx:
17223 case Intrinsic::ppc_altivec_lvxl:
17224 case Intrinsic::ppc_altivec_lvebx:
17225 case Intrinsic::ppc_altivec_lvehx:
17226 case Intrinsic::ppc_altivec_lvewx:
17227 case Intrinsic::ppc_vsx_lxvd2x:
17228 case Intrinsic::ppc_vsx_lxvw4x:
17229 case Intrinsic::ppc_vsx_lxvd2x_be:
17230 case Intrinsic::ppc_vsx_lxvw4x_be:
17231 case Intrinsic::ppc_vsx_lxvl:
17232 case Intrinsic::ppc_vsx_lxvll: {
17234 switch (Intrinsic) {
17235 case Intrinsic::ppc_altivec_lvebx:
17238 case Intrinsic::ppc_altivec_lvehx:
17241 case Intrinsic::ppc_altivec_lvewx:
17244 case Intrinsic::ppc_vsx_lxvd2x:
17245 case Intrinsic::ppc_vsx_lxvd2x_be:
17255 Info.ptrVal =
I.getArgOperand(0);
17262 case Intrinsic::ppc_altivec_stvx:
17263 case Intrinsic::ppc_altivec_stvxl:
17264 case Intrinsic::ppc_altivec_stvebx:
17265 case Intrinsic::ppc_altivec_stvehx:
17266 case Intrinsic::ppc_altivec_stvewx:
17267 case Intrinsic::ppc_vsx_stxvd2x:
17268 case Intrinsic::ppc_vsx_stxvw4x:
17269 case Intrinsic::ppc_vsx_stxvd2x_be:
17270 case Intrinsic::ppc_vsx_stxvw4x_be:
17271 case Intrinsic::ppc_vsx_stxvl:
17272 case Intrinsic::ppc_vsx_stxvll: {
17274 switch (Intrinsic) {
17275 case Intrinsic::ppc_altivec_stvebx:
17278 case Intrinsic::ppc_altivec_stvehx:
17281 case Intrinsic::ppc_altivec_stvewx:
17284 case Intrinsic::ppc_vsx_stxvd2x:
17285 case Intrinsic::ppc_vsx_stxvd2x_be:
17295 Info.ptrVal =
I.getArgOperand(1);
17302 case Intrinsic::ppc_stdcx:
17303 case Intrinsic::ppc_stwcx:
17304 case Intrinsic::ppc_sthcx:
17305 case Intrinsic::ppc_stbcx: {
17307 auto Alignment =
Align(8);
17308 switch (Intrinsic) {
17309 case Intrinsic::ppc_stdcx:
17312 case Intrinsic::ppc_stwcx:
17314 Alignment =
Align(4);
17316 case Intrinsic::ppc_sthcx:
17318 Alignment =
Align(2);
17320 case Intrinsic::ppc_stbcx:
17322 Alignment =
Align(1);
17327 Info.ptrVal =
I.getArgOperand(0);
17329 Info.align = Alignment;
17347 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17348 if (
Op.isMemset() && Subtarget.hasVSX()) {
17353 if (TailSize > 2 && TailSize <= 4) {
17358 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17377 return !(BitSize == 0 || BitSize > 64);
17385 return NumBits1 == 64 && NumBits2 == 32;
17393 return NumBits1 == 64 && NumBits2 == 32;
17399 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17400 EVT MemVT = LD->getMemoryVT();
17401 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17402 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17418 "invalid fpext types");
17420 if (DestVT == MVT::f128)
17426 return isInt<16>(Imm) || isUInt<16>(Imm);
17430 return isInt<16>(Imm) || isUInt<16>(Imm);
17435 unsigned *
Fast)
const {
17449 !Subtarget.allowsUnalignedFPAccess())
17453 if (Subtarget.hasVSX()) {
17454 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17455 VT != MVT::v4f32 && VT != MVT::v4i32)
17462 if (VT == MVT::ppcf128)
17476 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17477 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17485 int64_t Imm = ConstNode->getSExtValue();
17486 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17488 if (isInt<16>(Imm))
17513 return Subtarget.hasP9Vector();
17521 if (!
I->hasOneUse())
17525 assert(
User &&
"A single use instruction with no uses.");
17527 switch (
I->getOpcode()) {
17528 case Instruction::FMul: {
17530 if (
User->getOpcode() != Instruction::FSub &&
17531 User->getOpcode() != Instruction::FAdd)
17544 case Instruction::Load: {
17557 if (
User->getOpcode() != Instruction::Store)
17577 static const MCPhysReg ScratchRegs[] = {
17578 PPC::X12, PPC::LR8, PPC::CTR8, 0
17581 return ScratchRegs;
17585 const Constant *PersonalityFn)
const {
17586 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17590 const Constant *PersonalityFn)
const {
17591 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17596 EVT VT ,
unsigned DefinedValues)
const {
17597 if (VT == MVT::v2i64)
17598 return Subtarget.hasDirectMove();
17600 if (Subtarget.hasVSX())
17634 bool LegalOps,
bool OptForSize,
17636 unsigned Depth)
const {
17640 unsigned Opc =
Op.getOpcode();
17641 EVT VT =
Op.getValueType();
17666 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17670 N0Cost,
Depth + 1);
17674 N1Cost,
Depth + 1);
17676 if (NegN0 && N0Cost <= N1Cost) {
17677 Cost = std::min(N0Cost, N2Cost);
17678 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17679 }
else if (NegN1) {
17680 Cost = std::min(N1Cost, N2Cost);
17681 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17724 bool ForCodeSize)
const {
17725 if (!VT.
isSimple() || !Subtarget.hasVSX())
17735 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
17740 APSInt IntResult(16,
false);
17745 if (IsExact && IntResult <= 15 && IntResult >= -16)
17747 return Imm.isZero();
17750 return Imm.isPosZero();
17762 unsigned Opcode =
N->getOpcode();
17763 unsigned TargetOpcode;
17782 if (Mask->getZExtValue() == OpSizeInBits - 1)
17788SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17794 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17797 N->getValueType(0) != MVT::i64)
17812 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17818SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17825SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17844 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17846 Op.getValueType() != MVT::i64)
17850 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17851 Cmp.getOperand(0).getValueType() != MVT::i64)
17854 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
17855 int64_t NegConstant = 0 -
Constant->getSExtValue();
17858 return isInt<16>(NegConstant);
17864 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
17865 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
17868 if (LHSHasPattern && !RHSHasPattern)
17870 else if (!LHSHasPattern && !RHSHasPattern)
17876 SDValue Z = Cmp.getOperand(0);
17877 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
17878 int64_t NegConstant = 0 -
Constant->getSExtValue();
17880 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
17891 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17906 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17943 if (!GSDN || !ConstNode)
17950 if (!isInt<34>(NewOffset))
17963SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17983 DAGCombinerInfo &DCI)
const {
17985 if (Subtarget.useCRBits()) {
17987 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
17988 return CRTruncValue;
17995 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
17998 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18008 EltToExtract = EltToExtract ? 0 : 1;
18018 return DCI.DAG.getNode(
18020 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18025SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18029 if (!ConstOpOrElement)
18037 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18060 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18064 EVT VT =
N->getValueType(0);
18071 if ((MulAmtAbs - 1).isPowerOf2()) {
18075 if (!IsProfitable(IsNeg,
true, VT))
18088 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18092 if (!IsProfitable(IsNeg,
false, VT))
18113 DAGCombinerInfo &DCI)
const {
18118 EVT VT =
N->getValueType(0);
18121 unsigned Opc =
N->getOpcode();
18123 bool LegalOps = !DCI.isBeforeLegalizeOps();
18131 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18147bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18164 if (!Callee ||
Callee->isVarArg())
18177bool PPCTargetLowering::
18178isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18181 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18183 if (CI->getBitWidth() > 64)
18185 int64_t ConstVal = CI->getZExtValue();
18186 return isUInt<16>(ConstVal) ||
18187 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18196PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18202 if ((Flags & FlagSet) == FlagSet)
18205 if ((Flags & FlagSet) == FlagSet)
18208 if ((Flags & FlagSet) == FlagSet)
18211 if ((Flags & FlagSet) == FlagSet)
18232 if ((FrameIndexAlign % 4) != 0)
18233 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18234 if ((FrameIndexAlign % 16) != 0)
18235 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18239 if ((FrameIndexAlign % 4) == 0)
18241 if ((FrameIndexAlign % 16) == 0)
18254 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18255 if ((Imm & 0x3) == 0)
18257 if ((Imm & 0xf) == 0)
18263 const APInt &ConstImm = CN->getAPIntValue();
18282 const APInt &ConstImm = CN->getAPIntValue();
18292 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18304 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18305 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18306 isValidPCRelNode<JumpTableSDNode>(
N) ||
18307 isValidPCRelNode<BlockAddressSDNode>(
N));
18312unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18317 if (!Subtarget.hasP9Vector())
18322 if (Subtarget.hasPrefixInstrs())
18325 if (Subtarget.hasSPE())
18334 unsigned ParentOp = Parent->
getOpcode();
18338 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18339 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18350 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18351 if (LSB->isIndexed())
18356 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18357 assert(MN &&
"Parent should be a MemSDNode!");
18362 "Not expecting scalar integers larger than 16 bytes!");
18365 else if (
Size == 32)
18372 else if (
Size == 256) {
18373 assert(Subtarget.pairedVectorMemops() &&
18374 "256-bit vectors are only available when paired vector memops is "
18382 else if (MemVT == MVT::f128 || MemVT.
isVector())
18392 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18413 FlagSet &= ~PPC::MOF_NoExt;
18418 bool IsNonP1034BitConst =
18422 IsNonP1034BitConst)
18435 int16_t ForceXFormImm = 0;
18438 Disp =
N.getOperand(0);
18439 Base =
N.getOperand(1);
18450 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18451 Disp =
N.getOperand(0);
18452 Base =
N.getOperand(1);
18466 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18472 if (PartVT == MVT::f64 &&
18473 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18482SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18486 EVT RetVT =
Op.getValueType();
18494 EVT ArgVT =
N.getValueType();
18499 Entry.IsZExt = !Entry.IsSExt;
18500 Args.push_back(Entry);
18508 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18514 .setTailCall(isTailCall)
18521SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18522 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18524 if (
Op.getValueType() == MVT::f32)
18525 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18527 if (
Op.getValueType() == MVT::f64)
18528 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18533bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18535 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18539bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18540 return Op.getNode()->getFlags().hasApproximateFuncs();
18543bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18547SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18548 const char *LibCallFloatName,
18549 const char *LibCallDoubleNameFinite,
18550 const char *LibCallFloatNameFinite,
18553 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18556 if (!isLowringToMASSFiniteSafe(
Op))
18557 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18560 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18561 LibCallDoubleNameFinite,
Op, DAG);
18565 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18566 "__xl_powf_finite",
Op, DAG);
18570 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18571 "__xl_sinf_finite",
Op, DAG);
18575 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18576 "__xl_cosf_finite",
Op, DAG);
18580 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18581 "__xl_logf_finite",
Op, DAG);
18585 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18586 "__xl_log10f_finite",
Op, DAG);
18590 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18591 "__xl_expf_finite",
Op, DAG);
18598 if (!isa<FrameIndexSDNode>(
N))
18616 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18628 "Must be using PC-Relative calls when a valid PC-Relative node is "
18658 Disp =
N.getOperand(1).getOperand(0);
18663 Base =
N.getOperand(0);
18670 auto *CN = cast<ConstantSDNode>(
N);
18671 EVT CNType = CN->getValueType(0);
18672 uint64_t CNImm = CN->getZExtValue();
18683 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
18685 int32_t
Addr = (int32_t)CNImm;
18690 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18706 unsigned Opcode =
N.getOpcode();
18714 Base =
N.getOperand(0);
18733 Base = FI ?
N :
N.getOperand(1);
18745 bool IsVarArg)
const {
18755 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18789 return Intrinsic::ppc_atomicrmw_xchg_i128;
18791 return Intrinsic::ppc_atomicrmw_add_i128;
18793 return Intrinsic::ppc_atomicrmw_sub_i128;
18795 return Intrinsic::ppc_atomicrmw_and_i128;
18797 return Intrinsic::ppc_atomicrmw_or_i128;
18799 return Intrinsic::ppc_atomicrmw_xor_i128;
18801 return Intrinsic::ppc_atomicrmw_nand_i128;
18818 Value *LoHi = Builder.
CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
18824 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
18845 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
18852 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.
@ 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)