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()"));
147 "Number of shuffles lowered to a VPERM or XXPERM");
148STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
171 initializeAddrModeMap();
174 bool isPPC64 = Subtarget.
isPPC64();
183 if (!Subtarget.hasEFPU2())
208 if (Subtarget.isISA3_0()) {
238 if (!Subtarget.hasSPE()) {
246 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
247 for (
MVT VT : ScalarIntVTs) {
254 if (Subtarget.useCRBits()) {
257 if (isPPC64 || Subtarget.hasFPCVT()) {
260 isPPC64 ? MVT::i64 : MVT::i32);
263 isPPC64 ? MVT::i64 : MVT::i32);
267 isPPC64 ? MVT::i64 : MVT::i32);
270 isPPC64 ? MVT::i64 : MVT::i32);
274 isPPC64 ? MVT::i64 : MVT::i32);
277 isPPC64 ? MVT::i64 : MVT::i32);
281 isPPC64 ? MVT::i64 : MVT::i32);
284 isPPC64 ? MVT::i64 : MVT::i32);
331 if (Subtarget.isISA3_0()) {
366 if (!Subtarget.hasSPE()) {
371 if (Subtarget.hasVSX()) {
376 if (Subtarget.hasFSQRT()) {
381 if (Subtarget.hasFPRND()) {
422 if (Subtarget.hasSPE()) {
430 if (Subtarget.hasSPE())
436 if (!Subtarget.hasFSQRT() &&
437 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
441 if (!Subtarget.hasFSQRT() &&
442 !(
TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
443 Subtarget.hasFRES()))
446 if (Subtarget.hasFCPSGN()) {
454 if (Subtarget.hasFPRND()) {
468 if (Subtarget.isISA3_1()) {
479 if (Subtarget.isISA3_0()) {
499 if (!Subtarget.useCRBits()) {
512 if (!Subtarget.useCRBits())
515 if (Subtarget.hasFPU()) {
526 if (!Subtarget.useCRBits())
531 if (Subtarget.hasSPE()) {
555 if (Subtarget.hasDirectMove() && isPPC64) {
560 if (
TM.Options.UnsafeFPMath) {
663 if (Subtarget.hasSPE()) {
685 if (Subtarget.has64BitSupport()) {
700 if (Subtarget.hasLFIWAX() || Subtarget.
isPPC64()) {
706 if (Subtarget.hasSPE()) {
716 if (Subtarget.hasFPCVT()) {
717 if (Subtarget.has64BitSupport()) {
738 if (Subtarget.use64BitRegs()) {
756 if (Subtarget.has64BitSupport()) {
763 if (Subtarget.hasVSX()) {
770 if (Subtarget.hasAltivec()) {
771 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
786 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
799 if (Subtarget.hasVSX()) {
805 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
815 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
889 if (!Subtarget.hasP8Vector()) {
931 if (Subtarget.hasAltivec())
932 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
935 if (Subtarget.hasP8Altivec())
946 if (Subtarget.hasVSX()) {
952 if (Subtarget.hasP8Altivec())
957 if (Subtarget.isISA3_1()) {
995 if (Subtarget.hasVSX()) {
998 if (Subtarget.hasP8Vector()) {
1002 if (Subtarget.hasDirectMove() && isPPC64) {
1016 if (
TM.Options.UnsafeFPMath) {
1053 if (Subtarget.hasP8Vector())
1062 if (Subtarget.hasP8Altivec()) {
1089 if (Subtarget.isISA3_1())
1192 if (Subtarget.hasP8Altivec()) {
1197 if (Subtarget.hasP9Vector()) {
1202 if (Subtarget.useCRBits()) {
1261 }
else if (Subtarget.hasVSX()) {
1286 for (
MVT VT : {MVT::f32, MVT::f64}) {
1305 if (Subtarget.hasP9Altivec()) {
1306 if (Subtarget.isISA3_1()) {
1329 if (Subtarget.hasP10Vector()) {
1334 if (Subtarget.pairedVectorMemops()) {
1339 if (Subtarget.hasMMA()) {
1340 if (Subtarget.isISAFuture())
1349 if (Subtarget.has64BitSupport())
1352 if (Subtarget.isISA3_1())
1370 if (Subtarget.hasAltivec()) {
1397 if (Subtarget.hasFPCVT())
1400 if (Subtarget.useCRBits())
1409 if (Subtarget.useCRBits()) {
1440 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1441 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1442 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1443 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1448 if (Subtarget.useCRBits()) {
1553void PPCTargetLowering::initializeAddrModeMap() {
1604 if (MaxAlign == MaxMaxAlign)
1606 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1607 if (MaxMaxAlign >= 32 &&
1608 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1609 MaxAlign =
Align(32);
1610 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1612 MaxAlign =
Align(16);
1613 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1616 if (EltAlign > MaxAlign)
1617 MaxAlign = EltAlign;
1618 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1619 for (
auto *EltTy : STy->elements()) {
1622 if (EltAlign > MaxAlign)
1623 MaxAlign = EltAlign;
1624 if (MaxAlign == MaxMaxAlign)
1637 if (Subtarget.hasAltivec())
1639 return Alignment.
value();
1647 return Subtarget.hasSPE();
1655 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &
Index)
const {
1656 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1659 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1660 if (VTy->getScalarType()->isIntegerTy()) {
1662 if (ElemSizeInBits == 32) {
1666 if (ElemSizeInBits == 64) {
1692 return "PPCISD::FTSQRT";
1694 return "PPCISD::FSQRT";
1699 return "PPCISD::XXSPLTI_SP_TO_DP";
1701 return "PPCISD::XXSPLTI32DX";
1705 return "PPCISD::XXPERM";
1725 return "PPCISD::CALL_RM";
1727 return "PPCISD::CALL_NOP_RM";
1729 return "PPCISD::CALL_NOTOC_RM";
1734 return "PPCISD::BCTRL_RM";
1736 return "PPCISD::BCTRL_LOAD_TOC_RM";
1748 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1750 return "PPCISD::ANDI_rec_1_EQ_BIT";
1752 return "PPCISD::ANDI_rec_1_GT_BIT";
1767 return "PPCISD::ST_VSR_SCAL_INT";
1796 return "PPCISD::PADDI_DTPREL";
1812 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1814 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1824 return "PPCISD::STRICT_FADDRTZ";
1826 return "PPCISD::STRICT_FCTIDZ";
1828 return "PPCISD::STRICT_FCTIWZ";
1830 return "PPCISD::STRICT_FCTIDUZ";
1832 return "PPCISD::STRICT_FCTIWUZ";
1834 return "PPCISD::STRICT_FCFID";
1836 return "PPCISD::STRICT_FCFIDU";
1838 return "PPCISD::STRICT_FCFIDS";
1840 return "PPCISD::STRICT_FCFIDUS";
1843 return "PPCISD::STORE_COND";
1851 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1868 return CFP->getValueAPF().isZero();
1872 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1873 return CFP->getValueAPF().isZero();
1881 return Op < 0 ||
Op == Val;
1893 if (ShuffleKind == 0) {
1896 for (
unsigned i = 0; i != 16; ++i)
1899 }
else if (ShuffleKind == 2) {
1902 for (
unsigned i = 0; i != 16; ++i)
1905 }
else if (ShuffleKind == 1) {
1906 unsigned j = IsLE ? 0 : 1;
1907 for (
unsigned i = 0; i != 8; ++i)
1924 if (ShuffleKind == 0) {
1927 for (
unsigned i = 0; i != 16; i += 2)
1931 }
else if (ShuffleKind == 2) {
1934 for (
unsigned i = 0; i != 16; i += 2)
1938 }
else if (ShuffleKind == 1) {
1939 unsigned j = IsLE ? 0 : 2;
1940 for (
unsigned i = 0; i != 8; i += 2)
1961 if (!Subtarget.hasP8Vector())
1965 if (ShuffleKind == 0) {
1968 for (
unsigned i = 0; i != 16; i += 4)
1974 }
else if (ShuffleKind == 2) {
1977 for (
unsigned i = 0; i != 16; i += 4)
1983 }
else if (ShuffleKind == 1) {
1984 unsigned j = IsLE ? 0 : 4;
1985 for (
unsigned i = 0; i != 8; i += 4)
2002 unsigned LHSStart,
unsigned RHSStart) {
2003 if (
N->getValueType(0) != MVT::v16i8)
2005 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2006 "Unsupported merge size!");
2008 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2009 for (
unsigned j = 0; j != UnitSize; ++j) {
2011 LHSStart+j+i*UnitSize) ||
2013 RHSStart+j+i*UnitSize))
2028 if (ShuffleKind == 1)
2030 else if (ShuffleKind == 2)
2035 if (ShuffleKind == 1)
2037 else if (ShuffleKind == 0)
2053 if (ShuffleKind == 1)
2055 else if (ShuffleKind == 2)
2060 if (ShuffleKind == 1)
2062 else if (ShuffleKind == 0)
2112 unsigned RHSStartValue) {
2113 if (
N->getValueType(0) != MVT::v16i8)
2116 for (
unsigned i = 0; i < 2; ++i)
2117 for (
unsigned j = 0; j < 4; ++j)
2119 i*RHSStartValue+j+IndexOffset) ||
2121 i*RHSStartValue+j+IndexOffset+8))
2143 unsigned indexOffset = CheckEven ? 4 : 0;
2144 if (ShuffleKind == 1)
2146 else if (ShuffleKind == 2)
2152 unsigned indexOffset = CheckEven ? 0 : 4;
2153 if (ShuffleKind == 1)
2155 else if (ShuffleKind == 0)
2171 if (
N->getValueType(0) != MVT::v16i8)
2178 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2181 if (i == 16)
return -1;
2186 if (ShiftAmt < i)
return -1;
2191 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2193 for (++i; i != 16; ++i)
2196 }
else if (ShuffleKind == 1) {
2198 for (++i; i != 16; ++i)
2205 ShiftAmt = 16 - ShiftAmt;
2214 EVT VT =
N->getValueType(0);
2215 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2216 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2219 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2223 if (
N->getMaskElt(0) % EltSize != 0)
2228 unsigned ElementBase =
N->getMaskElt(0);
2231 if (ElementBase >= 16)
2236 for (
unsigned i = 1; i != EltSize; ++i)
2237 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2240 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2241 if (
N->getMaskElt(i) < 0)
continue;
2242 for (
unsigned j = 0; j != EltSize; ++j)
2243 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2260 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2261 "Unexpected element width.");
2262 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2264 unsigned NumOfElem = 16 / Width;
2265 unsigned MaskVal[16];
2266 for (
unsigned i = 0; i < NumOfElem; ++i) {
2267 MaskVal[0] =
N->getMaskElt(i * Width);
2268 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2270 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2274 for (
unsigned int j = 1; j < Width; ++j) {
2275 MaskVal[j] =
N->getMaskElt(i * Width + j);
2276 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2286 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2291 unsigned M0 =
N->getMaskElt(0) / 4;
2292 unsigned M1 =
N->getMaskElt(4) / 4;
2293 unsigned M2 =
N->getMaskElt(8) / 4;
2294 unsigned M3 =
N->getMaskElt(12) / 4;
2295 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2296 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2301 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2302 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2303 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2304 InsertAtByte = IsLE ? 12 : 0;
2309 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2310 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2311 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2312 InsertAtByte = IsLE ? 8 : 4;
2317 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2318 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2319 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2320 InsertAtByte = IsLE ? 4 : 8;
2325 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2326 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2327 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2328 InsertAtByte = IsLE ? 0 : 12;
2335 if (
N->getOperand(1).isUndef()) {
2338 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2339 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2340 InsertAtByte = IsLE ? 12 : 0;
2343 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2344 InsertAtByte = IsLE ? 8 : 4;
2347 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2348 InsertAtByte = IsLE ? 4 : 8;
2351 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2352 InsertAtByte = IsLE ? 0 : 12;
2361 bool &Swap,
bool IsLE) {
2362 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2368 unsigned M0 =
N->getMaskElt(0) / 4;
2369 unsigned M1 =
N->getMaskElt(4) / 4;
2370 unsigned M2 =
N->getMaskElt(8) / 4;
2371 unsigned M3 =
N->getMaskElt(12) / 4;
2375 if (
N->getOperand(1).isUndef()) {
2376 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2377 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2380 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2386 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2390 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2395 ShiftElts = (8 -
M0) % 8;
2396 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2401 ShiftElts = (4 -
M0) % 4;
2406 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2411 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2423 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2428 for (
int i = 0; i < 16; i += Width)
2429 if (
N->getMaskElt(i) != i + Width - 1)
2460 bool &Swap,
bool IsLE) {
2461 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2467 unsigned M0 =
N->getMaskElt(0) / 8;
2468 unsigned M1 =
N->getMaskElt(8) / 8;
2469 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2473 if (
N->getOperand(1).isUndef()) {
2474 if ((
M0 |
M1) < 2) {
2475 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2483 if (
M0 > 1 &&
M1 < 2) {
2485 }
else if (M0 < 2 && M1 > 1) {
2493 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2496 if (M0 < 2 && M1 > 1) {
2498 }
else if (
M0 > 1 &&
M1 < 2) {
2506 DM = (
M0 << 1) + (
M1 & 1);
2521 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2526 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2542 unsigned EltSize = 16/
N->getNumOperands();
2543 if (EltSize < ByteSize) {
2544 unsigned Multiple = ByteSize/EltSize;
2546 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2549 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2550 if (
N->getOperand(i).isUndef())
continue;
2552 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2554 if (!UniquedVals[i&(Multiple-1)].getNode())
2555 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2556 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2566 bool LeadingZero =
true;
2567 bool LeadingOnes =
true;
2568 for (
unsigned i = 0; i != Multiple-1; ++i) {
2569 if (!UniquedVals[i].getNode())
continue;
2576 if (!UniquedVals[Multiple-1].getNode())
2583 if (!UniquedVals[Multiple-1].getNode())
2585 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2594 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2595 if (
N->getOperand(i).isUndef())
continue;
2597 OpVal =
N->getOperand(i);
2598 else if (OpVal !=
N->getOperand(i))
2604 unsigned ValSizeInBytes = EltSize;
2607 Value = CN->getZExtValue();
2609 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2610 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2616 if (ValSizeInBytes < ByteSize)
return SDValue();
2627 if (MaskVal == 0)
return SDValue();
2630 if (SignExtend32<5>(MaskVal) == MaskVal)
2644 if (!isa<ConstantSDNode>(
N))
2647 Imm = (int16_t)
N->getAsZExtVal();
2648 if (
N->getValueType(0) == MVT::i32)
2649 return Imm == (int32_t)
N->getAsZExtVal();
2651 return Imm == (int64_t)
N->getAsZExtVal();
2669 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2678 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2679 if (Memop->getMemoryVT() == MVT::f64) {
2680 Base =
N.getOperand(0);
2693 if (!isa<ConstantSDNode>(
N))
2696 Imm = (int64_t)
N->getAsZExtVal();
2697 return isInt<34>(Imm);
2724 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2729 Base =
N.getOperand(0);
2732 }
else if (
N.getOpcode() ==
ISD::OR) {
2734 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2746 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2747 Base =
N.getOperand(0);
2818 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2824 Base =
N.getOperand(0);
2827 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2829 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2830 "Cannot handle constant offsets yet!");
2831 Disp =
N.getOperand(1).getOperand(0);
2836 Base =
N.getOperand(0);
2839 }
else if (
N.getOpcode() ==
ISD::OR) {
2842 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2852 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2856 Base =
N.getOperand(0);
2869 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2872 CN->getValueType(0));
2877 if ((CN->getValueType(0) == MVT::i32 ||
2878 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2879 (!EncodingAlignment ||
2880 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2881 int Addr = (int)CN->getZExtValue();
2888 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2909 if (
N.getValueType() != MVT::i64)
2922 Base =
N.getOperand(0);
2938 Base =
N.getOperand(0);
2971 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2972 Base =
N.getOperand(0);
2985 Ty *PCRelCand = dyn_cast<Ty>(
N);
2997 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
2998 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
2999 isValidPCRelNode<JumpTableSDNode>(
N) ||
3000 isValidPCRelNode<BlockAddressSDNode>(
N))
3016 EVT MemVT = LD->getMemoryVT();
3023 if (!ST.hasP8Vector())
3028 if (!ST.hasP9Vector())
3041 if (UI.getUse().get().getResNo() == 0 &&
3063 Ptr = LD->getBasePtr();
3064 VT = LD->getMemoryVT();
3065 Alignment = LD->getAlign();
3066 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3067 Ptr = ST->getBasePtr();
3068 VT = ST->getMemoryVT();
3069 Alignment = ST->getAlign();
3092 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3095 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3108 if (VT != MVT::i64) {
3113 if (Alignment <
Align(4))
3123 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3125 isa<ConstantSDNode>(
Offset))
3140 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3182 const bool Is64Bit = Subtarget.
isPPC64();
3183 EVT VT = Is64Bit ? MVT::i64 : MVT::i32;
3197 EVT PtrVT =
Op.getValueType();
3213 return getTOCEntry(DAG,
SDLoc(CP), GA);
3216 unsigned MOHiFlag, MOLoFlag;
3223 return getTOCEntry(DAG,
SDLoc(CP), GA);
3283 EVT PtrVT =
Op.getValueType();
3301 return getTOCEntry(DAG,
SDLoc(JT), GA);
3304 unsigned MOHiFlag, MOLoFlag;
3311 return getTOCEntry(DAG,
SDLoc(GA), GA);
3321 EVT PtrVT =
Op.getValueType();
3340 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3349 unsigned MOHiFlag, MOLoFlag;
3360 return LowerGlobalTLSAddressAIX(
Op, DAG);
3362 return LowerGlobalTLSAddressLinux(
Op, DAG);
3375 bool Is64Bit = Subtarget.
isPPC64();
3380 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3381 bool HasAIXSmallTLSGlobalAttr =
false;
3384 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3388 if (GVar->hasAttribute(
"aix-small-tls"))
3389 HasAIXSmallTLSGlobalAttr =
true;
3408 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3409 IsTLSLocalExecModel) {
3429 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3431 "currently only supported on AIX (64-bit mode).");
3437 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3441 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3443 "currently only supported on AIX (64-bit mode).");
3451 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3455 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3458 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3461 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3472 if (HasAIXSmallLocalDynamicTLS) {
3481 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3494 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3495 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3513 bool is64bit = Subtarget.
isPPC64();
3560 if (!
TM.isPositionIndependent())
3619 PtrVT, GOTPtr, TGA, TGA);
3621 PtrVT, TLSAddr, TGA);
3630 EVT PtrVT =
Op.getValueType();
3655 return getTOCEntry(DAG,
DL, GA);
3658 unsigned MOHiFlag, MOLoFlag;
3666 return getTOCEntry(DAG,
DL, GA);
3678 bool IsStrict =
Op->isStrictFPOpcode();
3680 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3684 EVT LHSVT =
LHS.getValueType();
3688 if (LHSVT == MVT::f128) {
3689 assert(!Subtarget.hasP9Vector() &&
3690 "SETCC for f128 is already legal under Power9!");
3701 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3703 if (
Op.getValueType() == MVT::v2i64) {
3706 if (
LHS.getValueType() == MVT::v2i64) {
3714 int ShuffV[] = {1, 0, 3, 2};
3719 dl, MVT::v4i32, Shuff, SetCC32));
3736 if (
C->isAllOnes() ||
C->isZero())
3746 EVT VT =
Op.getValueType();
3755 EVT VT =
Node->getValueType(0);
3759 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3769 if (VT == MVT::i64) {
3800 InChain = OverflowArea.
getValue(1);
3846 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3853 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3868 return Op.getOperand(0);
3877 "Expecting Inline ASM node.");
3887 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3893 unsigned NumVals =
Flags.getNumOperandRegisters();
3896 switch (
Flags.getKind()) {
3907 for (; NumVals; --NumVals, ++i) {
3908 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3909 if (Reg != PPC::LR && Reg != PPC::LR8)
3934 bool isPPC64 = (PtrVT == MVT::i64);
3940 Entry.Ty = IntPtrTy;
3941 Entry.Node = Trmp;
Args.push_back(Entry);
3944 Entry.Node = DAG.
getConstant(isPPC64 ? 48 : 40, dl,
3945 isPPC64 ? MVT::i64 : MVT::i32);
3946 Args.push_back(Entry);
3948 Entry.Node = FPtr;
Args.push_back(Entry);
3949 Entry.Node = Nest;
Args.push_back(Entry);
3953 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
3957 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
3958 return CallResult.second;
3972 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
3973 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4008 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4017 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4032 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4035 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4037 nextOffset += FrameOffset;
4038 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4041 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4047static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4048 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4049 PPC::F11, PPC::F12, PPC::F13};
4054 unsigned PtrByteSize) {
4056 if (Flags.isByVal())
4057 ArgSize = Flags.getByValSize();
4061 if (!Flags.isInConsecutiveRegs())
4062 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4071 unsigned PtrByteSize) {
4072 Align Alignment(PtrByteSize);
4075 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4076 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4077 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4078 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4079 Alignment =
Align(16);
4082 if (Flags.isByVal()) {
4083 auto BVAlign = Flags.getNonZeroByValAlign();
4084 if (BVAlign > PtrByteSize) {
4085 if (BVAlign.value() % PtrByteSize != 0)
4087 "ByVal alignment is not a multiple of the pointer size");
4089 Alignment = BVAlign;
4094 if (Flags.isInConsecutiveRegs()) {
4098 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4112 unsigned PtrByteSize,
unsigned LinkageSize,
4113 unsigned ParamAreaSize,
unsigned &ArgOffset,
4114 unsigned &AvailableFPRs,
4115 unsigned &AvailableVRs) {
4116 bool UseMemory =
false;
4121 ArgOffset =
alignTo(ArgOffset, Alignment);
4124 if (ArgOffset >= LinkageSize + ParamAreaSize)
4129 if (Flags.isInConsecutiveRegsLast())
4130 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4133 if (ArgOffset > LinkageSize + ParamAreaSize)
4138 if (!Flags.isByVal()) {
4139 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4140 if (AvailableFPRs > 0) {
4144 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4145 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4146 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4147 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4148 if (AvailableVRs > 0) {
4160 unsigned NumBytes) {
4164SDValue PPCTargetLowering::LowerFormalArguments(
4169 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4172 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4175 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4179SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4221 const Align PtrAlign(4);
4230 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4232 CCInfo.PreAnalyzeFormalArguments(Ins);
4235 CCInfo.clearWasPPCF128();
4237 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4250 RC = &PPC::GPRCRegClass;
4253 if (Subtarget.hasP8Vector())
4254 RC = &PPC::VSSRCRegClass;
4255 else if (Subtarget.hasSPE())
4256 RC = &PPC::GPRCRegClass;
4258 RC = &PPC::F4RCRegClass;
4261 if (Subtarget.hasVSX())
4262 RC = &PPC::VSFRCRegClass;
4263 else if (Subtarget.hasSPE())
4265 RC = &PPC::GPRCRegClass;
4267 RC = &PPC::F8RCRegClass;
4272 RC = &PPC::VRRCRegClass;
4275 RC = &PPC::VRRCRegClass;
4279 RC = &PPC::VRRCRegClass;
4286 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4287 assert(i + 1 < e &&
"No second half of double precision argument");
4299 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4300 if (ValVT == MVT::i1)
4315 ArgOffset += ArgSize - ObjSize;
4333 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4338 unsigned MinReservedArea = CCByValInfo.getStackSize();
4339 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4355 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4356 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4358 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4361 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4364 unsigned NumFPArgRegs = std::size(FPArgRegs);
4373 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4377 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4386 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4390 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4405 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4409 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4422 if (!MemOps.
empty())
4433 const SDLoc &dl)
const {
4437 else if (
Flags.isZExt())
4444SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4457 "fastcc not supported on varargs functions");
4463 unsigned PtrByteSize = 8;
4467 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4468 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4471 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4472 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4475 const unsigned Num_GPR_Regs = std::size(GPR);
4477 const unsigned Num_VR_Regs = std::size(VR);
4485 bool HasParameterArea = !isELFv2ABI || isVarArg;
4486 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4487 unsigned NumBytes = LinkageSize;
4488 unsigned AvailableFPRs = Num_FPR_Regs;
4489 unsigned AvailableVRs = Num_VR_Regs;
4490 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4491 if (Ins[i].
Flags.isNest())
4495 PtrByteSize, LinkageSize, ParamAreaSize,
4496 NumBytes, AvailableFPRs, AvailableVRs))
4497 HasParameterArea =
true;
4504 unsigned ArgOffset = LinkageSize;
4505 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4508 unsigned CurArgIdx = 0;
4509 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4511 bool needsLoad =
false;
4512 EVT ObjectVT =
Ins[ArgNo].VT;
4513 EVT OrigVT =
Ins[ArgNo].ArgVT;
4515 unsigned ArgSize = ObjSize;
4517 if (Ins[ArgNo].isOrigArg()) {
4518 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4519 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4524 unsigned CurArgOffset;
4526 auto ComputeArgOffset = [&]() {
4530 ArgOffset =
alignTo(ArgOffset, Alignment);
4531 CurArgOffset = ArgOffset;
4538 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4539 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4544 if (
Flags.isByVal()) {
4545 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4551 ObjSize =
Flags.getByValSize();
4552 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4574 if (HasParameterArea ||
4575 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4582 if (ObjSize < PtrByteSize) {
4586 if (!isLittleEndian) {
4592 if (GPR_idx != Num_GPR_Regs) {
4604 ArgOffset += PtrByteSize;
4613 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4614 if (GPR_idx == Num_GPR_Regs)
4625 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4633 ArgOffset += ArgSize;
4642 if (
Flags.isNest()) {
4647 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4648 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4656 if (GPR_idx != Num_GPR_Regs) {
4661 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4664 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4670 ArgSize = PtrByteSize;
4681 if (FPR_idx != Num_FPR_Regs) {
4684 if (ObjectVT == MVT::f32)
4686 Subtarget.hasP8Vector()
4687 ? &PPC::VSSRCRegClass
4688 : &PPC::F4RCRegClass);
4691 ? &PPC::VSFRCRegClass
4692 : &PPC::F8RCRegClass);
4707 if (ObjectVT == MVT::f32) {
4708 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4726 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4727 ArgOffset += ArgSize;
4728 if (
Flags.isInConsecutiveRegsLast())
4729 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4743 if (VR_idx != Num_VR_Regs) {
4760 if (ObjSize < ArgSize && !isLittleEndian)
4761 CurArgOffset += ArgSize - ObjSize;
4771 unsigned MinReservedArea;
4772 if (HasParameterArea)
4773 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4775 MinReservedArea = LinkageSize;
4792 int Depth = ArgOffset;
4801 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4802 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4814 if (!MemOps.
empty())
4823 unsigned ParamSize) {
4825 if (!isTailCall)
return 0;
4829 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4831 if (SPDiff < FI->getTailCallSPDelta())
4847 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4860 if (!
TM.shouldAssumeDSOLocal(CalleeGV))
4866 const Function *
F = dyn_cast<Function>(CalleeGV);
4867 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4872 F = dyn_cast<Function>(GlobalObj);
4905 if (
TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4906 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4908 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4909 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4921 const unsigned PtrByteSize = 8;
4925 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4926 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4929 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4930 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4933 const unsigned NumGPRs = std::size(GPR);
4934 const unsigned NumFPRs = 13;
4935 const unsigned NumVRs = std::size(VR);
4936 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
4938 unsigned NumBytes = LinkageSize;
4939 unsigned AvailableFPRs = NumFPRs;
4940 unsigned AvailableVRs = NumVRs;
4943 if (Param.Flags.isNest())
continue;
4946 LinkageSize, ParamAreaSize, NumBytes,
4947 AvailableFPRs, AvailableVRs))
4958 auto CalleeArgEnd = CB.
arg_end();
4961 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
4962 const Value* CalleeArg = *CalleeArgIter;
4963 const Value* CallerArg = &(*CallerArgIter);
4964 if (CalleeArg == CallerArg)
4972 isa<UndefValue>(CalleeArg))
4990 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5000bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5005 bool isCalleeExternalSymbol)
const {
5008 if (
DisableSCO && !TailCallOpt)
return false;
5011 if (isVarArg)
return false;
5087bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5121 if (!
C)
return nullptr;
5123 int Addr =
C->getZExtValue();
5124 if ((
Addr & 3) != 0 ||
5130 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5137struct TailCallArgumentInfo {
5142 TailCallArgumentInfo() =
default;
5152 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5153 SDValue Arg = TailCallArgs[i].Arg;
5154 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5155 int FI = TailCallArgs[i].FrameIdx;
5158 Chain, dl, Arg, FIN,
5167 int SPDiff,
const SDLoc &dl) {
5173 bool isPPC64 = Subtarget.
isPPC64();
5174 int SlotSize = isPPC64 ? 8 : 4;
5175 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5177 NewRetAddrLoc,
true);
5178 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5180 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5190 SDValue Arg,
int SPDiff,
unsigned ArgOffset,
5192 int Offset = ArgOffset + SPDiff;
5195 EVT VT = isPPC64 ? MVT::i64 : MVT::i32;
5197 TailCallArgumentInfo
Info;
5199 Info.FrameIdxOp = FIN;
5207SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5212 EVT VT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5213 LROpOut = getReturnAddrFrameIndex(DAG);
5230 return DAG.
getMemcpy(Chain, dl, Dst, Src, SizeNode,
5231 Flags.getNonZeroByValAlign(),
false,
false,
false,
5239 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5262 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5272 if (!MemOpChains2.
empty())
5296SDValue PPCTargetLowering::LowerCallResult(
5304 CCRetInfo.AnalyzeCallResult(
5310 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5316 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5319 Chain =
Lo.getValue(1);
5320 InGlue =
Lo.getValue(2);
5324 Chain =
Hi.getValue(1);
5325 InGlue =
Hi.getValue(2);
5362 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5394 bool IsStrictFPCall =
false) {
5398 unsigned RetOpc = 0;
5423 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5429 if (IsStrictFPCall) {
5460 auto isLocalCallee = [&]() {
5465 !isa_and_nonnull<GlobalIFunc>(GV);
5476 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5486 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5489 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5492 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5493 return getAIXFuncEntryPointSymbolSDNode(GV);
5500 const char *SymName = S->getSymbol();
5506 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5507 return getAIXFuncEntryPointSymbolSDNode(
F);
5513 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5521 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5528 assert(Callee.getNode() &&
"What no callee?");
5534 "Expected a CALLSEQ_STARTSDNode.");
5551 SDValue MTCTROps[] = {Chain, Callee, Glue};
5552 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5593 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5608 const MVT RegVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
5612 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5613 Alignment, MMOFlags);
5620 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5627 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5639 "Nest parameter is not supported on AIX.");
5655 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5658 const bool IsPPC64 = Subtarget.
isPPC64();
5660 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
5707 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5709 RegsToPass[i].second.getValueType()));
5726 assert(Mask &&
"Missing call preserved mask for calling convention");
5734SDValue PPCTargetLowering::FinishCall(
5749 if (!CFlags.IsIndirect)
5753 dl, CFlags.HasNest, Subtarget);
5763 if (CFlags.IsTailCall) {
5767 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5770 isa<ConstantSDNode>(Callee) ||
5772 "Expecting a global address, external symbol, absolute value, "
5773 "register or an indirect tail call when PC Relative calls are "
5777 "Unexpected call opcode for a tail call.");
5784 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5785 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5797 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5800 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5811 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5820 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5821 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5825bool PPCTargetLowering::isEligibleForTCO(
5830 bool isCalleeExternalSymbol)
const {
5835 return IsEligibleForTailCallOptimization_64SVR4(
5836 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5837 isCalleeExternalSymbol);
5839 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5862 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5864 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5867 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5881 isa<GlobalAddressSDNode>(Callee)) &&
5882 "Callee should be an llvm::Function object.");
5885 <<
"\nTCO callee: ");
5892 "site marked musttail");
5897 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5899 Callee = LowerGlobalAddress(Callee, DAG);
5902 CallConv, isTailCall, isVarArg, isPatchPoint,
5910 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5915 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5917 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5921SDValue PPCTargetLowering::LowerCall_32SVR4(
5932 const bool IsVarArg = CFlags.IsVarArg;
5933 const bool IsTailCall = CFlags.IsTailCall;
5939 const Align PtrAlign(4);
5964 CCInfo.PreAnalyzeCallOperands(Outs);
5970 unsigned NumArgs = Outs.
size();
5972 for (
unsigned i = 0; i != NumArgs; ++i) {
5973 MVT ArgVT = Outs[i].VT;
5977 if (Outs[i].IsFixed) {
5987 errs() <<
"Call operand #" << i <<
" has unhandled type "
5997 CCInfo.clearWasPPCF128();
6004 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6011 unsigned NumBytes = CCByValInfo.getStackSize();
6025 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6036 bool seenFloatArg =
false;
6041 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6043 ++i, ++RealArgIdx) {
6045 SDValue Arg = OutVals[RealArgIdx];
6048 if (
Flags.isByVal()) {
6053 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6076 Chain = CallSeqStart = NewCallSeqStart;
6095 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6102 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6126 if (!MemOpChains.
empty())
6132 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6133 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6134 RegsToPass[i].second, InGlue);
6142 SDValue Ops[] = { Chain, InGlue };
6154 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6155 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6160SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6172 return NewCallSeqStart;
6175SDValue PPCTargetLowering::LowerCall_64SVR4(
6184 unsigned NumOps = Outs.
size();
6185 bool IsSibCall =
false;
6189 unsigned PtrByteSize = 8;
6204 assert(!(IsFastCall && CFlags.IsVarArg) &&
6205 "fastcc not supported on varargs functions");
6212 unsigned NumBytes = LinkageSize;
6213 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6216 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6217 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6220 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6221 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6224 const unsigned NumGPRs = std::size(GPR);
6226 const unsigned NumVRs = std::size(VR);
6232 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6233 if (!HasParameterArea) {
6234 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6235 unsigned AvailableFPRs = NumFPRs;
6236 unsigned AvailableVRs = NumVRs;
6237 unsigned NumBytesTmp = NumBytes;
6238 for (
unsigned i = 0; i != NumOps; ++i) {
6239 if (Outs[i].
Flags.isNest())
continue;
6241 PtrByteSize, LinkageSize, ParamAreaSize,
6242 NumBytesTmp, AvailableFPRs, AvailableVRs))
6243 HasParameterArea =
true;
6249 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6254 HasParameterArea =
false;
6257 for (
unsigned i = 0; i != NumOps; ++i) {
6259 EVT ArgVT = Outs[i].VT;
6260 EVT OrigVT = Outs[i].ArgVT;
6266 if (
Flags.isByVal()) {
6267 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6268 if (NumGPRsUsed > NumGPRs)
6269 HasParameterArea =
true;
6276 if (++NumGPRsUsed <= NumGPRs)
6286 if (++NumVRsUsed <= NumVRs)
6290 if (++NumVRsUsed <= NumVRs)
6295 if (++NumFPRsUsed <= NumFPRs)
6299 HasParameterArea =
true;
6306 NumBytes =
alignTo(NumBytes, Alignement);
6309 if (
Flags.isInConsecutiveRegsLast())
6310 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6313 unsigned NumBytesActuallyUsed = NumBytes;
6323 if (HasParameterArea)
6324 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6326 NumBytes = LinkageSize;
6341 if (CFlags.IsTailCall)
6353 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6364 unsigned ArgOffset = LinkageSize;
6370 for (
unsigned i = 0; i != NumOps; ++i) {
6373 EVT ArgVT = Outs[i].VT;
6374 EVT OrigVT = Outs[i].ArgVT;
6383 auto ComputePtrOff = [&]() {
6387 ArgOffset =
alignTo(ArgOffset, Alignment);
6398 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6399 GPR_idx = std::min(GPR_idx, NumGPRs);
6406 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6412 if (
Flags.isByVal()) {
6430 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6431 if (GPR_idx != NumGPRs) {
6435 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6437 ArgOffset += PtrByteSize;
6442 if (GPR_idx == NumGPRs &&
Size < 8) {
6444 if (!isLittleEndian) {
6449 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6452 ArgOffset += PtrByteSize;
6461 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6462 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6467 if (
Size < 8 && GPR_idx != NumGPRs) {
6477 if (!isLittleEndian) {
6481 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6489 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6492 ArgOffset += PtrByteSize;
6498 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6501 if (GPR_idx != NumGPRs) {
6502 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6508 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6509 ArgOffset += PtrByteSize;
6511 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6523 if (
Flags.isNest()) {
6525 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6532 if (GPR_idx != NumGPRs) {
6533 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6538 assert(HasParameterArea &&
6539 "Parameter area must exist to pass an argument in memory.");
6541 true, CFlags.IsTailCall,
false, MemOpChains,
6542 TailCallArguments, dl);
6544 ArgOffset += PtrByteSize;
6547 ArgOffset += PtrByteSize;
6560 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6561 bool NeededLoad =
false;
6564 if (FPR_idx != NumFPRs)
6565 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6568 if (!NeedGPROrStack)
6570 else if (GPR_idx != NumGPRs && !IsFastCall) {
6584 }
else if (!
Flags.isInConsecutiveRegs()) {
6590 }
else if (ArgOffset % PtrByteSize != 0) {
6594 if (!isLittleEndian)
6599 }
else if (
Flags.isInConsecutiveRegsLast()) {
6602 if (!isLittleEndian)
6612 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6620 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6625 assert(HasParameterArea &&
6626 "Parameter area must exist to pass an argument in memory.");
6628 true, CFlags.IsTailCall,
false, MemOpChains,
6629 TailCallArguments, dl);
6636 if (!IsFastCall || NeededLoad) {
6638 Flags.isInConsecutiveRegs()) ? 4 : 8;
6639 if (
Flags.isInConsecutiveRegsLast())
6640 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6660 if (CFlags.IsVarArg) {
6661 assert(HasParameterArea &&
6662 "Parameter area must exist if we have a varargs call.");
6668 if (VR_idx != NumVRs) {
6672 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6675 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6676 if (GPR_idx == NumGPRs)
6683 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6689 if (VR_idx != NumVRs) {
6690 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6695 assert(HasParameterArea &&
6696 "Parameter area must exist to pass an argument in memory.");
6698 true, CFlags.IsTailCall,
true, MemOpChains,
6699 TailCallArguments, dl);
6710 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6711 "mismatch in size of parameter area");
6712 (void)NumBytesActuallyUsed;
6714 if (!MemOpChains.
empty())
6720 if (CFlags.IsIndirect) {
6724 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6739 if (isELFv2ABI && !CFlags.IsPatchPoint)
6740 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6746 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6747 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6748 RegsToPass[i].second, InGlue);
6752 if (CFlags.IsTailCall && !IsSibCall)
6756 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6757 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6764 "Required alignment greater than stack alignment.");
6784 return RequiredAlign <= 8;
6789 return RequiredAlign <= 4;
6799 const bool IsPPC64 = Subtarget.
isPPC64();
6801 const MVT RegVT = IsPPC64 ? MVT::i64 : MVT::i32;
6803 if (ValVT == MVT::f128)
6810 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6811 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6813 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6814 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6817 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6818 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6819 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6824 "register width are not supported.");
6830 if (ByValSize == 0) {
6836 const unsigned StackSize =
alignTo(ByValSize, PtrAlign);
6838 for (
const unsigned E =
Offset + StackSize;
Offset < E;
6840 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6858 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6867 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32))
6887 for (
unsigned I = 0;
I < StoreSize;
I += PtrAlign.
value()) {
6888 if (
unsigned Reg = State.
AllocateReg(IsPPC64 ? GPR_64 : GPR_32)) {
6889 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
6922 const unsigned VecSize = 16;
6923 const Align VecAlign(VecSize);
6940 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6946 while (NextRegIndex != GPRs.
size() &&
6951 assert(Reg &&
"Allocating register unexpectedly failed.");
6964 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
6976 if (NextRegIndex == GPRs.
size()) {
6985 if (GPRs[NextRegIndex] == PPC::R9) {
6990 const unsigned FirstReg = State.
AllocateReg(PPC::R9);
6991 const unsigned SecondReg = State.
AllocateReg(PPC::R10);
6992 assert(FirstReg && SecondReg &&
6993 "Allocating R9 or R10 unexpectedly failed.");
7007 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7009 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7024 assert((IsPPC64 || SVT != MVT::i64) &&
7025 "i64 should have been split for 32-bit codegen.");
7033 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7035 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7037 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7045 return &PPC::VRRCRegClass;
7058 else if (Flags.isZExt())
7068 if (PPC::GPRCRegClass.
contains(Reg)) {
7069 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7070 "Reg must be a valid argument register!");
7071 return LASize + 4 * (Reg - PPC::R3);
7074 if (PPC::G8RCRegClass.
contains(Reg)) {
7075 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7076 "Reg must be a valid argument register!");
7077 return LASize + 8 * (Reg - PPC::X3);
7123SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7130 "Unexpected calling convention!");
7140 const bool IsPPC64 = Subtarget.
isPPC64();
7141 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7153 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7154 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7172 auto HandleMemLoc = [&]() {
7175 assert((ValSize <= LocSize) &&
7176 "Object size is larger than size of MemLoc");
7179 if (LocSize > ValSize)
7180 CurArgOffset += LocSize - ValSize;
7182 const bool IsImmutable =
7197 assert(isVarArg &&
"Only use custom memloc for vararg.");
7200 const unsigned OriginalValNo = VA.
getValNo();
7201 (void)OriginalValNo;
7203 auto HandleCustomVecRegLoc = [&]() {
7204 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7205 "Missing custom RegLoc.");
7208 "Unexpected Val type for custom RegLoc.");
7210 "ValNo mismatch between custom MemLoc and RegLoc.");
7214 Subtarget.hasVSX()));
7221 HandleCustomVecRegLoc();
7222 HandleCustomVecRegLoc();
7226 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7228 "Only 2 custom RegLocs expected for 64-bit codegen.");
7229 HandleCustomVecRegLoc();
7230 HandleCustomVecRegLoc();
7274 const unsigned Size =
7286 if (
Flags.isByVal()) {
7292 if (
Flags.getNonZeroByValAlign() > PtrByteSize)
7295 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7304 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7306 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7319 CopyFrom.
getValue(1), dl, CopyFrom,
7329 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7332 "RegLocs should be for ByVal argument.");
7339 if (
Offset != StackSize) {
7341 "Expected MemLoc for remaining bytes.");
7342 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7356 Subtarget.hasVSX()));
7373 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7375 unsigned CallerReservedArea = std::max<unsigned>(
7376 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7382 CallerReservedArea =
7391 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7392 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7394 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7395 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7396 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7401 for (
unsigned GPRIndex =
7402 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7403 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7406 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7407 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7419 if (!MemOps.
empty())
7425SDValue PPCTargetLowering::LowerCall_AIX(
7438 "Unexpected calling convention!");
7440 if (CFlags.IsPatchPoint)
7447 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7455 const bool IsPPC64 = Subtarget.
isPPC64();
7457 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7458 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7459 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7467 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7468 const unsigned NumBytes = std::max<unsigned>(
7469 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7485 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7486 const unsigned ValNo = ArgLocs[
I].getValNo();
7490 if (
Flags.isByVal()) {
7491 const unsigned ByValSize =
Flags.getByValSize();
7499 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7508 unsigned LoadOffset = 0;
7511 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7514 LoadOffset += PtrByteSize;
7517 "Unexpected location for pass-by-value argument.");
7521 if (LoadOffset == ByValSize)
7525 assert(ArgLocs[
I].getValNo() == ValNo &&
7526 "Expected additional location for by-value argument.");
7528 if (ArgLocs[
I].isMemLoc()) {
7529 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7534 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7540 CallSeqStart, MemcpyFlags, DAG, dl);
7549 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7550 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7551 "Unexpected register residue for by-value argument.");
7553 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7557 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7567 "Unexpected load emitted during handling of pass-by-value "
7575 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7610 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7618 const unsigned OriginalValNo = VA.
getValNo();
7620 unsigned LoadOffset = 0;
7621 auto HandleCustomVecRegLoc = [&]() {
7622 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7623 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7624 "Expected custom RegLoc.");
7627 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7633 LoadOffset += PtrByteSize;
7639 HandleCustomVecRegLoc();
7640 HandleCustomVecRegLoc();
7642 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7643 ArgLocs[
I].getValNo() == OriginalValNo) {
7645 "Only 2 custom RegLocs expected for 64-bit codegen.");
7646 HandleCustomVecRegLoc();
7647 HandleCustomVecRegLoc();
7665 "Unexpected register handling for calling convention.");
7671 "Custom register handling only expected for VarArg.");
7689 "Unexpected custom register for argument!");
7710 if (!MemOpChains.
empty())
7715 if (CFlags.IsIndirect) {
7716 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7719 const MVT PtrVT = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
7720 const unsigned TOCSaveOffset =
7736 for (
auto Reg : RegsToPass) {
7741 const int SPDiff = 0;
7742 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7743 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7752 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7753 return CCInfo.CheckReturn(
7768 CCInfo.AnalyzeReturn(Outs,
7777 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7781 SDValue Arg = OutVals[RealResIdx];
7796 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7819 RetOps.push_back(Glue);
7825PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7830 EVT IntVT =
Op.getValueType();
7834 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7836 SDValue Ops[2] = {Chain, FPSIdx};
7850 bool isPPC64 = Subtarget.
isPPC64();
7851 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7871 bool isPPC64 = Subtarget.
isPPC64();
7892PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
7894 bool isPPC64 = Subtarget.
isPPC64();
7928 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7929 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
7940 bool isPPC64 = Subtarget.
isPPC64();
7952 Op.getOperand(0),
Op.getOperand(1));
7959 Op.getOperand(0),
Op.getOperand(1));
7963 if (
Op.getValueType().isVector())
7964 return LowerVectorLoad(
Op, DAG);
7966 assert(
Op.getValueType() == MVT::i1 &&
7967 "Custom lowering only for i1 loads");
7980 BasePtr, MVT::i8, MMO);
7988 if (
Op.getOperand(1).getValueType().isVector())
7989 return LowerVectorStore(
Op, DAG);
7991 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
7992 "Custom lowering only for i1 stores");
8011 assert(
Op.getValueType() == MVT::i1 &&
8012 "Custom lowering only for i1 results");
8040 EVT TrgVT =
Op.getValueType();
8053 !llvm::has_single_bit<uint32_t>(
8064 if (SrcSize == 256) {
8075 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8083 for (
unsigned i = 0; i < TrgNumElts; ++i)
8086 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8090 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8103 EVT ResVT =
Op.getValueType();
8104 EVT CmpVT =
Op.getOperand(0).getValueType();
8106 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8112 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8129 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8161 if (
LHS.getValueType() == MVT::f32)
8174 if (
LHS.getValueType() == MVT::f32)
8183 if (
LHS.getValueType() == MVT::f32)
8197 if (
Cmp.getValueType() == MVT::f32)
8207 if (
Cmp.getValueType() == MVT::f32)
8213 if (
Cmp.getValueType() == MVT::f32)
8219 if (
Cmp.getValueType() == MVT::f32)
8225 if (
Cmp.getValueType() == MVT::f32)
8258 bool IsStrict =
Op->isStrictFPOpcode();
8264 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8267 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8269 MVT DestTy =
Op.getSimpleValueType();
8270 assert(Src.getValueType().isFloatingPoint() &&
8271 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8272 DestTy == MVT::i64) &&
8273 "Invalid FP_TO_INT types");
8274 if (Src.getValueType() == MVT::f32) {
8278 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8279 Chain = Src.getValue(1);
8283 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8284 DestTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
8293 assert((IsSigned || Subtarget.hasFPCVT()) &&
8294 "i64 FP_TO_UINT is supported only with FPCVT");
8297 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8301 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8304 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8309void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8311 const SDLoc &dl)
const {
8315 bool IsStrict =
Op->isStrictFPOpcode();
8318 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8319 (IsSigned || Subtarget.hasFPCVT());
8321 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8330 Alignment =
Align(4);
8333 SDValue Ops[] = { Chain, Tmp, FIPtr };
8335 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8337 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8341 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8350 RLI.Alignment = Alignment;
8358 const SDLoc &dl)
const {
8361 if (
Op->isStrictFPOpcode())
8368 const SDLoc &dl)
const {
8369 bool IsStrict =
Op->isStrictFPOpcode();
8372 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8373 EVT SrcVT = Src.getValueType();
8374 EVT DstVT =
Op.getValueType();
8377 if (SrcVT == MVT::f128)
8378 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8382 if (SrcVT == MVT::ppcf128) {
8383 if (DstVT == MVT::i32) {
8388 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8399 {Op.getOperand(0), Lo, Hi}, Flags);
8402 {Res.getValue(1), Res}, Flags);
8408 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8432 {Chain, Src, FltOfs}, Flags);
8436 {Chain, Val}, Flags);
8439 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8457 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8458 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8461 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8463 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8464 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8475bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8480 if (
Op->isStrictFPOpcode())
8485 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8489 Op.getOperand(0).getValueType())) {
8491 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8496 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8497 LD->isNonTemporal())
8499 if (
LD->getMemoryVT() != MemVT)
8509 RLI.Ptr =
LD->getBasePtr();
8510 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8512 "Non-pre-inc AM on PPC?");
8517 RLI.Chain =
LD->getChain();
8518 RLI.MPI =
LD->getPointerInfo();
8519 RLI.IsDereferenceable =
LD->isDereferenceable();
8520 RLI.IsInvariant =
LD->isInvariant();
8521 RLI.Alignment =
LD->getAlign();
8522 RLI.AAInfo =
LD->getAAInfo();
8523 RLI.Ranges =
LD->getRanges();
8525 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8533void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8539 SDLoc dl(NewResChain);
8542 NewResChain, DAG.
getUNDEF(MVT::Other));
8544 "A new TF really is required here");
8553bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8554 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8561 if (!Subtarget.hasP9Vector() &&
8570 if (UI.getUse().get().getResNo() != 0)
8592 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8596 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8599 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8600 if (
Op->isStrictFPOpcode()) {
8602 Chain =
Op.getOperand(0);
8604 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8606 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8614 const SDLoc &dl)
const {
8615 assert((
Op.getValueType() == MVT::f32 ||
8616 Op.getValueType() == MVT::f64) &&
8617 "Invalid floating point type as target of conversion");
8618 assert(Subtarget.hasFPCVT() &&
8619 "Int to FP conversions with direct moves require FPCVT");
8620 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8621 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8643 for (
unsigned i = 1; i < NumConcat; ++i)
8650 const SDLoc &dl)
const {
8651 bool IsStrict =
Op->isStrictFPOpcode();
8652 unsigned Opc =
Op.getOpcode();
8653 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8656 "Unexpected conversion type");
8657 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8658 "Supports conversions to v2f64/v4f32 only.");
8662 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8665 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8670 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8673 for (
unsigned i = 0; i < WideNumElts; ++i)
8676 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8677 int SaveElts = FourEltRes ? 4 : 2;
8679 for (
int i = 0; i < SaveElts; i++)
8680 ShuffV[i * Stride] = i;
8682 for (
int i = 1; i <= SaveElts; i++)
8683 ShuffV[i * Stride - 1] = i - 1;
8691 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8692 EVT ExtVT = Src.getValueType();
8693 if (Subtarget.hasP9Altivec())
8704 {Op.getOperand(0), Extend}, Flags);
8706 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8714 bool IsStrict =
Op->isStrictFPOpcode();
8715 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8720 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8722 EVT InVT = Src.getValueType();
8723 EVT OutVT =
Op.getValueType();
8726 return LowerINT_TO_FPVector(
Op, DAG, dl);
8729 if (
Op.getValueType() == MVT::f128)
8730 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8733 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8736 if (Src.getValueType() == MVT::i1) {
8748 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8749 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8750 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8752 assert((IsSigned || Subtarget.hasFPCVT()) &&
8753 "UINT_TO_FP is supported only with FPCVT");
8755 if (Src.getValueType() == MVT::i64) {
8767 if (
Op.getValueType() == MVT::f32 &&
8768 !Subtarget.hasFPCVT() &&
8809 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8810 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8811 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8812 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8813 }
else if (Subtarget.hasLFIWAX() &&
8814 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8817 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8818 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8821 Ops, MVT::i32, MMO);
8822 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8823 }
else if (Subtarget.hasFPCVT() &&
8824 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8827 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8828 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8831 Ops, MVT::i32, MMO);
8832 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8833 }
else if (((Subtarget.hasLFIWAX() &&
8835 (Subtarget.hasFPCVT() &&
8849 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8850 "Expected an i32 store");
8856 RLI.Alignment =
Align(4);
8860 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8861 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8864 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8865 Ops, MVT::i32, MMO);
8866 Chain =
Bits.getValue(1);
8872 Chain =
FP.getValue(1);
8874 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8878 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8886 assert(Src.getValueType() == MVT::i32 &&
8887 "Unhandled INT_TO_FP type in custom expander!");
8897 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
8900 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
8909 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8910 "Expected an i32 store");
8916 RLI.Alignment =
Align(4);
8921 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8922 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8924 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
8928 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
8931 "i32->FP without LFIWAX supported only on PPC64");
8940 Chain, dl, Ext64, FIdx,
8946 MVT::f64, dl, Chain, FIdx,
8954 Chain =
FP.getValue(1);
8955 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8959 {Chain, FP, DAG.getIntPtrConstant(0, dl)}, Flags);
8990 EVT VT =
Op.getValueType();
8996 Chain =
MFFS.getValue(1);
9010 "Stack slot adjustment is valid only on big endian subtargets!");
9040 EVT VT =
Op.getValueType();
9044 VT ==
Op.getOperand(1).getValueType() &&
9064 SDValue OutOps[] = { OutLo, OutHi };
9069 EVT VT =
Op.getValueType();
9073 VT ==
Op.getOperand(1).getValueType() &&
9093 SDValue OutOps[] = { OutLo, OutHi };
9099 EVT VT =
Op.getValueType();
9102 VT ==
Op.getOperand(1).getValueType() &&
9122 SDValue OutOps[] = { OutLo, OutHi };
9129 EVT VT =
Op.getValueType();
9136 EVT AmtVT =
Z.getValueType();
9159 static const MVT VTys[] = {
9160 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9163 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9166 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9171 EVT CanonicalVT = VTys[SplatSize-1];
9180 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9181 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9190 EVT DestVT = MVT::Other) {
9191 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9200 EVT DestVT = MVT::Other) {
9203 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9215 for (
unsigned i = 0; i != 16; ++i)
9236 EVT VecVT = V->getValueType(0);
9237 bool RightType = VecVT == MVT::v2f64 ||
9238 (HasP8Vector && VecVT == MVT::v4f32) ||
9239 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9243 bool IsSplat =
true;
9244 bool IsLoad =
false;
9245 SDValue Op0 = V->getOperand(0);
9250 if (V->isConstant())
9252 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9253 if (V->getOperand(i).isUndef())
9257 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9259 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9261 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9263 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9267 if (V->getOperand(i) != Op0 ||
9268 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9271 return !(IsSplat && IsLoad);
9280 if ((
Op.getValueType() != MVT::f128) ||
9301 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9309 APFloat APFloatToConvert = ArgAPFloat;
9310 bool LosesInfo =
true;
9315 ArgAPFloat = APFloatToConvert;
9337 APFloat APFloatToConvert = ArgAPFloat;
9338 bool LosesInfo =
true;
9342 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9347 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9351 EVT Ty =
Op->getValueType(0);
9354 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9363 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9367 if (Ty == MVT::v2i64) {
9370 if (MemVT == MVT::i32) {
9390 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9393 APInt APSplatBits, APSplatUndef;
9394 unsigned SplatBitSize;
9396 bool BVNIsConstantSplat =
9404 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9405 Subtarget.hasPrefixInstrs()) {
9408 if ((
Op->getValueType(0) == MVT::v2f64) &&
9443 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9450 const SDValue *InputLoad = &
Op.getOperand(0);
9455 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9456 unsigned ElementSize =
9459 assert(((ElementSize == 2 * MemorySize)
9463 "Unmatched element size and opcode!\n");
9468 unsigned NumUsesOfInputLD = 128 / ElementSize;
9470 if (BVInOp.isUndef())
9485 if (NumUsesOfInputLD == 1 &&
9488 Subtarget.hasLFIWAX()))
9497 Subtarget.isISA3_1() && ElementSize <= 16)
9500 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9502 Subtarget.hasVSX()) {
9509 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9510 LD->getMemoryVT(),
LD->getMemOperand());
9522 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9524 Subtarget.hasP8Vector()))
9531 unsigned SplatSize = SplatBitSize / 8;
9536 if (SplatBits == 0) {
9538 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9550 if (Subtarget.hasPrefixInstrs() && SplatSize == 2)
9552 Op.getValueType(), DAG, dl);
9554 if (Subtarget.hasPrefixInstrs() && SplatSize == 4)
9559 if (Subtarget.hasP9Vector() && SplatSize == 1)
9564 int32_t SextVal= (int32_t(SplatBits << (32-SplatBitSize)) >>
9566 if (SextVal >= -16 && SextVal <= 15)
9579 if (SextVal >= -32 && SextVal <= 31) {
9584 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9585 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9588 if (VT ==
Op.getValueType())
9597 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9611 static const signed char SplatCsts[] = {
9612 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9613 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9616 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9619 int i = SplatCsts[idx];
9623 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9626 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9628 static const unsigned IIDs[] = {
9629 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9630 Intrinsic::ppc_altivec_vslw
9637 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9639 static const unsigned IIDs[] = {
9640 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9641 Intrinsic::ppc_altivec_vsrw
9648 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9649 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9651 static const unsigned IIDs[] = {
9652 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9653 Intrinsic::ppc_altivec_vrlw
9660 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9666 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9672 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9687 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9688 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9689 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9705 if (LHSID == (1*9+2)*9+3)
return LHS;
9706 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9718 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9719 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9720 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9721 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9724 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9725 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9726 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9727 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9730 for (
unsigned i = 0; i != 16; ++i)
9731 ShufIdxs[i] = (i&3)+0;
9734 for (
unsigned i = 0; i != 16; ++i)
9735 ShufIdxs[i] = (i&3)+4;
9738 for (
unsigned i = 0; i != 16; ++i)
9739 ShufIdxs[i] = (i&3)+8;
9742 for (
unsigned i = 0; i != 16; ++i)
9743 ShufIdxs[i] = (i&3)+12;
9764 const unsigned BytesInVector = 16;
9769 unsigned ShiftElts = 0, InsertAtByte = 0;
9773 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9774 0, 15, 14, 13, 12, 11, 10, 9};
9775 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
9776 1, 2, 3, 4, 5, 6, 7, 8};
9779 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
9791 bool FoundCandidate =
false;
9795 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
9798 for (
unsigned i = 0; i < BytesInVector; ++i) {
9799 unsigned CurrentElement =
Mask[i];
9802 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
9805 bool OtherElementsInOrder =
true;
9808 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
9815 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
9816 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
9817 OtherElementsInOrder =
false;
9824 if (OtherElementsInOrder) {
9831 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
9832 : BigEndianShifts[CurrentElement & 0xF];
9833 Swap = CurrentElement < BytesInVector;
9835 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
9836 FoundCandidate =
true;
9841 if (!FoundCandidate)
9865 const unsigned NumHalfWords = 8;
9866 const unsigned BytesInVector = NumHalfWords * 2;
9875 unsigned ShiftElts = 0, InsertAtByte = 0;
9879 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
9880 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
9883 uint32_t OriginalOrderLow = 0x1234567;
9884 uint32_t OriginalOrderHigh = 0x89ABCDEF;
9887 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9888 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9889 Mask |= ((
uint32_t)(
N->getMaskElt(i * 2) / 2) << MaskShift);
9905 bool FoundCandidate =
false;
9908 for (
unsigned i = 0; i < NumHalfWords; ++i) {
9909 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
9911 uint32_t MaskOtherElts = ~(0xF << MaskShift);
9919 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
9920 TargetOrder = OriginalOrderLow;
9924 if (MaskOneElt == VINSERTHSrcElem &&
9925 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9926 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9927 FoundCandidate =
true;
9933 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
9935 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
9937 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
9938 : BigEndianShifts[MaskOneElt & 0x7];
9939 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
9940 Swap = MaskOneElt < NumHalfWords;
9941 FoundCandidate =
true;
9947 if (!FoundCandidate)
9982 auto ShuffleMask = SVN->
getMask();
9997 ShuffleMask = CommutedSV->
getMask();
10006 APInt APSplatValue, APSplatUndef;
10007 unsigned SplatBitSize;
10023 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10024 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10025 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10027 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10028 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10029 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10037 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10038 SplatVal |= (SplatVal << SplatBitSize);
10052 assert(
Op.getValueType() == MVT::v1i128 &&
10053 "Only set v1i128 as custom, other type shouldn't reach here!");
10058 if (SHLAmt % 8 == 0) {
10059 std::array<int, 16>
Mask;
10060 std::iota(
Mask.begin(),
Mask.end(), 0);
10061 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10090 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10091 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10094 SVOp = cast<ShuffleVectorSDNode>(
Op);
10095 V1 =
Op.getOperand(0);
10096 V2 =
Op.getOperand(1);
10098 EVT VT =
Op.getValueType();
10101 unsigned ShiftElts, InsertAtByte;
10107 bool IsPermutedLoad =
false;
10109 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10119 if (IsPermutedLoad) {
10120 assert((isLittleEndian || IsFourByte) &&
10121 "Unexpected size for permuted load on big endian target");
10122 SplatIdx += IsFourByte ? 2 : 1;
10123 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10124 "Splat of a value outside of the loaded memory");
10129 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10132 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10134 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10138 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10151 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10154 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10163 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10166 if (Subtarget.hasP9Vector() &&
10187 if (Subtarget.hasPrefixInstrs()) {
10189 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10190 return SplatInsertNode;
10193 if (Subtarget.hasP9Altivec()) {
10195 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10198 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10202 if (Subtarget.hasVSX() &&
10215 if (Subtarget.hasVSX() &&
10228 if (Subtarget.hasP9Vector()) {
10248 if (Subtarget.hasVSX()) {
10269 if (
V2.isUndef()) {
10282 (Subtarget.hasP8Altivec() && (
10293 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10303 (Subtarget.hasP8Altivec() && (
10314 unsigned PFIndexes[4];
10315 bool isFourElementShuffle =
true;
10316 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10318 unsigned EltNo = 8;
10319 for (
unsigned j = 0;
j != 4; ++
j) {
10320 if (PermMask[i * 4 + j] < 0)
10323 unsigned ByteSource = PermMask[i * 4 +
j];
10324 if ((ByteSource & 3) != j) {
10325 isFourElementShuffle =
false;
10330 EltNo = ByteSource / 4;
10331 }
else if (EltNo != ByteSource / 4) {
10332 isFourElementShuffle =
false;
10336 PFIndexes[i] = EltNo;
10344 if (isFourElementShuffle) {
10346 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10347 PFIndexes[2] * 9 + PFIndexes[3];
10350 unsigned Cost = (PFEntry >> 30);
10370 if (
V2.isUndef())
V2 = V1;
10372 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10381 bool NeedSwap =
false;
10383 bool isPPC64 = Subtarget.
isPPC64();
10385 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10387 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10388 "XXPERM instead\n");
10394 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10395 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10397 NeedSwap = !NeedSwap;
10432 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10434 if (V1HasXXSWAPD) {
10437 else if (SrcElt < 16)
10440 if (V2HasXXSWAPD) {
10443 else if (SrcElt > 15)
10452 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10453 if (isLittleEndian)
10455 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10458 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10461 if (V1HasXXSWAPD) {
10465 if (V2HasXXSWAPD) {
10466 dl =
SDLoc(
V2->getOperand(0));
10467 V2 =
V2->getOperand(0)->getOperand(1);
10470 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10471 if (ValType != MVT::v2f64)
10473 if (
V2.getValueType() != MVT::v2f64)
10477 ShufflesHandledWithVPERM++;
10482 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10484 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10487 dbgs() <<
"With the following permute control vector:\n";
10492 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10496 if (isLittleEndian)
10502 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10514 switch (IntrinsicID) {
10518 case Intrinsic::ppc_altivec_vcmpbfp_p:
10522 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10526 case Intrinsic::ppc_altivec_vcmpequb_p:
10530 case Intrinsic::ppc_altivec_vcmpequh_p:
10534 case Intrinsic::ppc_altivec_vcmpequw_p:
10538 case Intrinsic::ppc_altivec_vcmpequd_p:
10539 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10545 case Intrinsic::ppc_altivec_vcmpneb_p:
10546 case Intrinsic::ppc_altivec_vcmpneh_p:
10547 case Intrinsic::ppc_altivec_vcmpnew_p:
10548 case Intrinsic::ppc_altivec_vcmpnezb_p:
10549 case Intrinsic::ppc_altivec_vcmpnezh_p:
10550 case Intrinsic::ppc_altivec_vcmpnezw_p:
10551 if (Subtarget.hasP9Altivec()) {
10552 switch (IntrinsicID) {
10555 case Intrinsic::ppc_altivec_vcmpneb_p:
10558 case Intrinsic::ppc_altivec_vcmpneh_p:
10561 case Intrinsic::ppc_altivec_vcmpnew_p:
10564 case Intrinsic::ppc_altivec_vcmpnezb_p:
10567 case Intrinsic::ppc_altivec_vcmpnezh_p:
10570 case Intrinsic::ppc_altivec_vcmpnezw_p:
10578 case Intrinsic::ppc_altivec_vcmpgefp_p:
10582 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10586 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10590 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10594 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10598 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10599 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10605 case Intrinsic::ppc_altivec_vcmpgtub_p:
10609 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10613 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10617 case Intrinsic::ppc_altivec_vcmpgtud_p:
10618 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10625 case Intrinsic::ppc_altivec_vcmpequq:
10626 case Intrinsic::ppc_altivec_vcmpgtsq:
10627 case Intrinsic::ppc_altivec_vcmpgtuq:
10628 if (!Subtarget.isISA3_1())
10630 switch (IntrinsicID) {
10633 case Intrinsic::ppc_altivec_vcmpequq:
10636 case Intrinsic::ppc_altivec_vcmpgtsq:
10639 case Intrinsic::ppc_altivec_vcmpgtuq:
10646 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10647 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10648 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10649 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10650 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10651 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10652 if (Subtarget.hasVSX()) {
10653 switch (IntrinsicID) {
10654 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10657 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10660 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10663 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10666 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10669 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10679 case Intrinsic::ppc_altivec_vcmpbfp:
10682 case Intrinsic::ppc_altivec_vcmpeqfp:
10685 case Intrinsic::ppc_altivec_vcmpequb:
10688 case Intrinsic::ppc_altivec_vcmpequh:
10691 case Intrinsic::ppc_altivec_vcmpequw:
10694 case Intrinsic::ppc_altivec_vcmpequd:
10695 if (Subtarget.hasP8Altivec())
10700 case Intrinsic::ppc_altivec_vcmpneb:
10701 case Intrinsic::ppc_altivec_vcmpneh:
10702 case Intrinsic::ppc_altivec_vcmpnew:
10703 case Intrinsic::ppc_altivec_vcmpnezb:
10704 case Intrinsic::ppc_altivec_vcmpnezh:
10705 case Intrinsic::ppc_altivec_vcmpnezw:
10706 if (Subtarget.hasP9Altivec())
10707 switch (IntrinsicID) {
10710 case Intrinsic::ppc_altivec_vcmpneb:
10713 case Intrinsic::ppc_altivec_vcmpneh:
10716 case Intrinsic::ppc_altivec_vcmpnew:
10719 case Intrinsic::ppc_altivec_vcmpnezb:
10722 case Intrinsic::ppc_altivec_vcmpnezh:
10725 case Intrinsic::ppc_altivec_vcmpnezw:
10732 case Intrinsic::ppc_altivec_vcmpgefp:
10735 case Intrinsic::ppc_altivec_vcmpgtfp:
10738 case Intrinsic::ppc_altivec_vcmpgtsb:
10741 case Intrinsic::ppc_altivec_vcmpgtsh:
10744 case Intrinsic::ppc_altivec_vcmpgtsw:
10747 case Intrinsic::ppc_altivec_vcmpgtsd:
10748 if (Subtarget.hasP8Altivec())
10753 case Intrinsic::ppc_altivec_vcmpgtub:
10756 case Intrinsic::ppc_altivec_vcmpgtuh:
10759 case Intrinsic::ppc_altivec_vcmpgtuw:
10762 case Intrinsic::ppc_altivec_vcmpgtud:
10763 if (Subtarget.hasP8Altivec())
10768 case Intrinsic::ppc_altivec_vcmpequq_p:
10769 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10770 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10771 if (!Subtarget.isISA3_1())
10773 switch (IntrinsicID) {
10776 case Intrinsic::ppc_altivec_vcmpequq_p:
10779 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10782 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10796 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
10800 switch (IntrinsicID) {
10801 case Intrinsic::thread_pointer:
10807 case Intrinsic::ppc_rldimi: {
10808 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
10812 return Op.getOperand(2);
10813 if (
Mask.isAllOnes())
10816 unsigned MB = 0, ME = 0;
10820 if (ME < 63 - SH) {
10823 }
else if (ME > 63 - SH) {
10829 {Op.getOperand(2), Src,
10830 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
10831 DAG.getTargetConstant(MB, dl, MVT::i32)}),
10835 case Intrinsic::ppc_rlwimi: {
10838 return Op.getOperand(2);
10839 if (
Mask.isAllOnes())
10842 unsigned MB = 0, ME = 0;
10846 PPC::RLWIMI, dl, MVT::i32,
10847 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
10848 DAG.getTargetConstant(MB, dl, MVT::i32),
10849 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10853 case Intrinsic::ppc_rlwnm: {
10854 if (
Op.getConstantOperandVal(3) == 0)
10856 unsigned MB = 0, ME = 0;
10861 {Op.getOperand(1), Op.getOperand(2),
10862 DAG.getTargetConstant(MB, dl, MVT::i32),
10863 DAG.getTargetConstant(ME, dl, MVT::i32)}),
10867 case Intrinsic::ppc_mma_disassemble_acc: {
10868 if (Subtarget.isISAFuture()) {
10869 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
10907 case Intrinsic::ppc_vsx_disassemble_pair: {
10910 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
10915 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
10926 case Intrinsic::ppc_mma_xxmfacc:
10927 case Intrinsic::ppc_mma_xxmtacc: {
10929 if (!Subtarget.isISAFuture())
10940 case Intrinsic::ppc_unpack_longdouble: {
10941 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
10942 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
10943 "Argument of long double unpack must be 0 or 1!");
10946 Idx->getValueType(0)));
10949 case Intrinsic::ppc_compare_exp_lt:
10950 case Intrinsic::ppc_compare_exp_gt:
10951 case Intrinsic::ppc_compare_exp_eq:
10952 case Intrinsic::ppc_compare_exp_uo: {
10954 switch (IntrinsicID) {
10955 case Intrinsic::ppc_compare_exp_lt:
10958 case Intrinsic::ppc_compare_exp_gt:
10961 case Intrinsic::ppc_compare_exp_eq:
10964 case Intrinsic::ppc_compare_exp_uo:
10970 PPC::SELECT_CC_I4, dl, MVT::i32,
10971 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
10972 Op.getOperand(1), Op.getOperand(2)),
10974 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10975 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
10978 case Intrinsic::ppc_test_data_class: {
10979 EVT OpVT =
Op.getOperand(1).getValueType();
10980 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
10981 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
10985 PPC::SELECT_CC_I4, dl, MVT::i32,
10986 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
10989 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
10990 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
10993 case Intrinsic::ppc_fnmsub: {
10994 EVT VT =
Op.getOperand(1).getValueType();
10995 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11001 Op.getOperand(2),
Op.getOperand(3));
11003 case Intrinsic::ppc_convert_f128_to_ppcf128:
11004 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11005 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11006 ? RTLIB::CONVERT_PPCF128_F128
11007 : RTLIB::CONVERT_F128_PPCF128;
11008 MakeLibCallOptions CallOptions;
11009 std::pair<SDValue, SDValue>
Result =
11010 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11014 case Intrinsic::ppc_maxfe:
11015 case Intrinsic::ppc_maxfl:
11016 case Intrinsic::ppc_maxfs:
11017 case Intrinsic::ppc_minfe:
11018 case Intrinsic::ppc_minfl:
11019 case Intrinsic::ppc_minfs: {
11020 EVT VT =
Op.getValueType();
11023 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11024 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11027 if (IntrinsicID == Intrinsic::ppc_minfe ||
11028 IntrinsicID == Intrinsic::ppc_minfl ||
11029 IntrinsicID == Intrinsic::ppc_minfs)
11051 Op.getOperand(1),
Op.getOperand(2),
11062 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11074 switch (
Op.getConstantOperandVal(1)) {
11077 BitNo = 0; InvertBit =
false;
11080 BitNo = 0; InvertBit =
true;
11083 BitNo = 2; InvertBit =
false;
11086 BitNo = 2; InvertBit =
true;
11108 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11110 switch (
Op.getConstantOperandVal(ArgStart)) {
11111 case Intrinsic::ppc_cfence: {
11112 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11113 SDValue Val =
Op.getOperand(ArgStart + 1);
11115 if (Ty == MVT::i128) {
11120 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11121 EVT FTy = Subtarget.
isPPC64() ? MVT::i64 : MVT::i32;
11145 int VectorIndex = 0;
11158 "Expecting an atomic compare-and-swap here.");
11160 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11161 EVT MemVT = AtomicNode->getMemoryVT();
11179 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11180 Ops.
push_back(AtomicNode->getOperand(i));
11192 EVT MemVT =
N->getMemoryVT();
11194 "Expect quadword atomic operations");
11196 unsigned Opc =
N->getOpcode();
11204 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11205 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11208 Ops, MemVT,
N->getMemOperand());
11215 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11225 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11235 N->getMemOperand());
11247 enum DataClassMask {
11249 DC_NEG_INF = 1 << 4,
11250 DC_POS_INF = 1 << 5,
11251 DC_NEG_ZERO = 1 << 2,
11252 DC_POS_ZERO = 1 << 3,
11253 DC_NEG_SUBNORM = 1,
11254 DC_POS_SUBNORM = 1 << 1,
11257 EVT VT =
Op.getValueType();
11259 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11260 : VT == MVT::f64 ? PPC::XSTSTDCDP
11271 return DAG.
getNOT(Dl, Rev, MVT::i1);
11278 TestOp, Dl, MVT::i32,
11280 DC_NEG_ZERO | DC_POS_ZERO |
11281 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11287 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11293 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11298 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11311 bool IsQuiet = Mask &
fcQNan;
11317 if (VT == MVT::f128) {
11321 QuietMask = 0x8000;
11322 }
else if (VT == MVT::f64) {
11334 QuietMask = 0x80000;
11335 }
else if (VT == MVT::f32) {
11337 QuietMask = 0x400000;
11353 unsigned NativeMask = 0;
11355 NativeMask |= DC_NAN;
11357 NativeMask |= DC_NEG_INF;
11359 NativeMask |= DC_POS_INF;
11361 NativeMask |= DC_NEG_ZERO;
11363 NativeMask |= DC_POS_ZERO;
11365 NativeMask |= DC_NEG_SUBNORM;
11367 NativeMask |= DC_POS_SUBNORM;
11370 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11372 TestOp, Dl, MVT::i32,
11381 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11383 uint64_t RHSC =
Op.getConstantOperandVal(1);
11408 "Should only be called for ISD::INSERT_VECTOR_ELT");
11412 EVT VT =
Op.getValueType();
11417 if (VT == MVT::v2f64 &&
C)
11420 if (Subtarget.hasP9Vector()) {
11429 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11430 (isa<LoadSDNode>(V2))) {
11435 BitcastLoad,
Op.getOperand(2));
11436 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11440 if (Subtarget.isISA3_1()) {
11441 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11445 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11446 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11456 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11459 unsigned InsertAtElement =
C->getZExtValue();
11460 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11462 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11476 EVT VT =
Op.getValueType();
11478 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11484 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11485 "Type unsupported without MMA");
11486 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11487 "Type unsupported without paired vector support");
11492 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11494 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11504 std::reverse(Loads.
begin(), Loads.
end());
11505 std::reverse(LoadChains.
begin(), LoadChains.
end());
11523 EVT StoreVT =
Value.getValueType();
11525 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11531 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11532 "Type unsupported without MMA");
11533 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11534 "Type unsupported without paired vector support");
11537 unsigned NumVecs = 2;
11538 if (StoreVT == MVT::v512i1) {
11539 if (Subtarget.isISAFuture()) {
11540 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11542 PPC::DMXXEXTFDMR512, dl,
ArrayRef(ReturnTypes, 2),
Op.getOperand(1));
11545 Value2 =
SDValue(ExtNode, 1);
11550 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11553 if (Subtarget.isISAFuture()) {
11563 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11577 if (
Op.getValueType() == MVT::v4i32) {
11594 LHS, RHS, DAG, dl, MVT::v4i32);
11597 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11602 }
else if (
Op.getValueType() == MVT::v16i8) {
11608 LHS, RHS, DAG, dl, MVT::v8i16);
11613 LHS, RHS, DAG, dl, MVT::v8i16);
11621 for (
unsigned i = 0; i != 8; ++i) {
11622 if (isLittleEndian) {
11624 Ops[i*2+1] = 2*i+16;
11627 Ops[i*2+1] = 2*i+1+16;
11630 if (isLittleEndian)
11640 bool IsStrict =
Op->isStrictFPOpcode();
11641 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11642 !Subtarget.hasP9Vector())
11652 "Should only be called for ISD::FP_EXTEND");
11656 if (
Op.getValueType() != MVT::v2f64 ||
11657 Op.getOperand(0).getValueType() != MVT::v2f32)
11669 "Node should have 2 operands with second one being a constant!");
11681 int DWord =
Idx >> 1;
11704 LD->getMemoryVT(),
LD->getMemOperand());
11717 LD->getMemoryVT(),
LD->getMemOperand());
11728 switch (
Op.getOpcode()) {
11757 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
11783 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
11784 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
11796 return LowerFP_ROUND(
Op, DAG);
11809 return LowerINTRINSIC_VOID(
Op, DAG);
11811 return LowerBSWAP(
Op, DAG);
11813 return LowerATOMIC_CMP_SWAP(
Op, DAG);
11815 return LowerATOMIC_LOAD_STORE(
Op, DAG);
11817 return LowerIS_FPCLASS(
Op, DAG);
11825 switch (
N->getOpcode()) {
11827 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
11844 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
11847 assert(
N->getValueType(0) == MVT::i1 &&
11848 "Unexpected result type for CTR decrement intrinsic");
11850 N->getValueType(0));
11860 switch (
N->getConstantOperandVal(0)) {
11861 case Intrinsic::ppc_pack_longdouble:
11863 N->getOperand(2),
N->getOperand(1)));
11865 case Intrinsic::ppc_maxfe:
11866 case Intrinsic::ppc_minfe:
11867 case Intrinsic::ppc_fnmsub:
11868 case Intrinsic::ppc_convert_f128_to_ppcf128:
11878 EVT VT =
N->getValueType(0);
11880 if (VT == MVT::i64) {
11893 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
11897 Results.push_back(LoweredValue);
11898 if (
N->isStrictFPOpcode())
11903 if (!
N->getValueType(0).isVector())
11954 if (isa<LoadInst>(Inst))
11958 Intrinsic::ppc_cfence, {Inst->getType()}),
11968 unsigned AtomicSize,
11969 unsigned BinOpcode,
11970 unsigned CmpOpcode,
11971 unsigned CmpPred)
const {
11975 auto LoadMnemonic = PPC::LDARX;
11976 auto StoreMnemonic = PPC::STDCX;
11977 switch (AtomicSize) {
11981 LoadMnemonic = PPC::LBARX;
11982 StoreMnemonic = PPC::STBCX;
11983 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11986 LoadMnemonic = PPC::LHARX;
11987 StoreMnemonic = PPC::STHCX;
11988 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
11991 LoadMnemonic = PPC::LWARX;
11992 StoreMnemonic = PPC::STWCX;
11995 LoadMnemonic = PPC::LDARX;
11996 StoreMnemonic = PPC::STDCX;
12012 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12014 F->insert(It, loopMBB);
12016 F->insert(It, loop2MBB);
12017 F->insert(It, exitMBB);
12023 Register TmpReg = (!BinOpcode) ? incr :
12025 : &PPC::GPRCRegClass);
12050 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12057 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12059 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12087 switch(
MI.getOpcode()) {
12091 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12092 &
MI.getMF()->getRegInfo());
12116 case PPC::EXTSB8_32_64:
12117 case PPC::EXTSB8_rec:
12118 case PPC::EXTSB_rec:
12121 case PPC::EXTSH8_32_64:
12122 case PPC::EXTSH8_rec:
12123 case PPC::EXTSH_rec:
12125 case PPC::EXTSWSLI:
12126 case PPC::EXTSWSLI_32_64:
12127 case PPC::EXTSWSLI_32_64_rec:
12128 case PPC::EXTSWSLI_rec:
12129 case PPC::EXTSW_32:
12130 case PPC::EXTSW_32_64:
12131 case PPC::EXTSW_32_64_rec:
12132 case PPC::EXTSW_rec:
12135 case PPC::SRAWI_rec:
12136 case PPC::SRAW_rec:
12145 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12155 bool IsSignExtended =
12158 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12160 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12161 .
addReg(
MI.getOperand(3).getReg());
12162 MI.getOperand(3).setReg(ValueReg);
12166 if (Subtarget.hasPartwordAtomics())
12174 bool is64bit = Subtarget.
isPPC64();
12176 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12187 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12189 F->insert(It, loopMBB);
12191 F->insert(It, loop2MBB);
12192 F->insert(It, exitMBB);
12198 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12243 if (ptrA != ZeroReg) {
12245 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12253 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12254 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12257 .
addImm(is8bit ? 28 : 27);
12258 if (!isLittleEndian)
12259 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12261 .
addImm(is8bit ? 24 : 16);
12263 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12268 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12278 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12282 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12287 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12291 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12294 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12306 unsigned ValueReg = SReg;
12307 unsigned CmpReg = Incr2Reg;
12308 if (CmpOpcode == PPC::CMPW) {
12310 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12314 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12316 ValueReg = ValueSReg;
12348 .
addImm(is8bit ? 24 : 16)
12369 Register DstReg =
MI.getOperand(0).getReg();
12371 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12372 Register mainDstReg =
MRI.createVirtualRegister(RC);
12373 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12376 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12377 "Invalid Pointer Size!");
12425 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12426 Register BufReg =
MI.getOperand(1).getReg();
12441 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12443 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12446 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12469 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12490 TII->get(PPC::PHI), DstReg)
12494 MI.eraseFromParent();
12508 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12509 "Invalid Pointer Size!");
12512 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12515 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12516 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12530 Register BufReg =
MI.getOperand(0).getReg();
12535 if (PVT == MVT::i64) {
12547 if (PVT == MVT::i64) {
12559 if (PVT == MVT::i64) {
12571 if (PVT == MVT::i64) {
12583 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12593 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12596 MI.eraseFromParent();
12612 "Unexpected stack alignment");
12616 unsigned StackProbeSize =
12619 StackProbeSize &= ~(StackAlign - 1);
12620 return StackProbeSize ? StackProbeSize : StackAlign;
12632 const bool isPPC64 = Subtarget.
isPPC64();
12664 MF->
insert(MBBIter, TestMBB);
12665 MF->
insert(MBBIter, BlockMBB);
12666 MF->
insert(MBBIter, TailMBB);
12671 Register DstReg =
MI.getOperand(0).getReg();
12672 Register NegSizeReg =
MI.getOperand(1).getReg();
12673 Register SPReg = isPPC64 ? PPC::X1 : PPC::R1;
12674 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12675 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12676 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12682 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
12684 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
12690 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
12691 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
12693 .
addDef(ActualNegSizeReg)
12695 .
add(
MI.getOperand(2))
12696 .
add(
MI.getOperand(3));
12702 .
addReg(ActualNegSizeReg);
12705 int64_t NegProbeSize = -(int64_t)ProbeSize;
12706 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
12707 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12708 if (!isInt<16>(NegProbeSize)) {
12709 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12711 .
addImm(NegProbeSize >> 16);
12715 .
addImm(NegProbeSize & 0xFFFF);
12722 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12724 .
addReg(ActualNegSizeReg)
12726 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12730 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12733 .
addReg(ActualNegSizeReg);
12742 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
12743 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
12757 BuildMI(BlockMBB,
DL,
TII->get(isPPC64 ? PPC::STDUX : PPC::STWUX), SPReg)
12768 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
12770 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
12771 MaxCallFrameSizeReg)
12772 .
add(
MI.getOperand(2))
12773 .
add(
MI.getOperand(3));
12774 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
12776 .
addReg(MaxCallFrameSizeReg);
12785 MI.eraseFromParent();
12787 ++NumDynamicAllocaProbed;
12792 switch (
MI.getOpcode()) {
12793 case PPC::SELECT_CC_I4:
12794 case PPC::SELECT_CC_I8:
12795 case PPC::SELECT_CC_F4:
12796 case PPC::SELECT_CC_F8:
12797 case PPC::SELECT_CC_F16:
12798 case PPC::SELECT_CC_VRRC:
12799 case PPC::SELECT_CC_VSFRC:
12800 case PPC::SELECT_CC_VSSRC:
12801 case PPC::SELECT_CC_VSRC:
12802 case PPC::SELECT_CC_SPE4:
12803 case PPC::SELECT_CC_SPE:
12811 switch (
MI.getOpcode()) {
12812 case PPC::SELECT_I4:
12813 case PPC::SELECT_I8:
12814 case PPC::SELECT_F4:
12815 case PPC::SELECT_F8:
12816 case PPC::SELECT_F16:
12817 case PPC::SELECT_SPE:
12818 case PPC::SELECT_SPE4:
12819 case PPC::SELECT_VRRC:
12820 case PPC::SELECT_VSFRC:
12821 case PPC::SELECT_VSSRC:
12822 case PPC::SELECT_VSRC:
12832 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
12833 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
12835 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
12848 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
12849 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
12851 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
12852 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
12866 if (Subtarget.hasISEL() &&
12867 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12868 MI.getOpcode() == PPC::SELECT_CC_I8 ||
12869 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
12871 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
12872 MI.getOpcode() == PPC::SELECT_CC_I8)
12873 Cond.push_back(
MI.getOperand(4));
12876 Cond.push_back(
MI.getOperand(1));
12879 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
12880 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
12896 F->insert(It, copy0MBB);
12897 F->insert(It, sinkMBB);
12901 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
12916 .
addReg(
MI.getOperand(1).getReg())
12919 unsigned SelectPred =
MI.getOperand(4).getImm();
12922 .
addReg(
MI.getOperand(1).getReg())
12939 .
addReg(
MI.getOperand(3).getReg())
12941 .
addReg(
MI.getOperand(2).getReg())
12943 }
else if (
MI.getOpcode() == PPC::ReadTB) {
12959 F->insert(It, readMBB);
12960 F->insert(It, sinkMBB);
12981 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
12991 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
12993 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
12995 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
12997 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13000 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13002 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13004 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13006 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13009 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13011 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13013 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13015 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13018 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13020 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13022 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13024 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13027 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13029 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13031 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13033 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13036 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13038 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13040 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13042 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13045 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13047 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13049 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13051 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13054 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13056 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13058 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13060 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13063 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13065 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13067 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13069 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13072 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13074 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13076 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13078 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13081 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13083 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13085 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13087 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13089 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13090 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13091 (Subtarget.hasPartwordAtomics() &&
13092 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13093 (Subtarget.hasPartwordAtomics() &&
13094 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13095 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13097 auto LoadMnemonic = PPC::LDARX;
13098 auto StoreMnemonic = PPC::STDCX;
13099 switch (
MI.getOpcode()) {
13102 case PPC::ATOMIC_CMP_SWAP_I8:
13103 LoadMnemonic = PPC::LBARX;
13104 StoreMnemonic = PPC::STBCX;
13105 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13107 case PPC::ATOMIC_CMP_SWAP_I16:
13108 LoadMnemonic = PPC::LHARX;
13109 StoreMnemonic = PPC::STHCX;
13110 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13112 case PPC::ATOMIC_CMP_SWAP_I32:
13113 LoadMnemonic = PPC::LWARX;
13114 StoreMnemonic = PPC::STWCX;
13116 case PPC::ATOMIC_CMP_SWAP_I64:
13117 LoadMnemonic = PPC::LDARX;
13118 StoreMnemonic = PPC::STDCX;
13126 Register oldval =
MI.getOperand(3).getReg();
13127 Register newval =
MI.getOperand(4).getReg();
13133 F->insert(It, loop1MBB);
13134 F->insert(It, loop2MBB);
13135 F->insert(It, exitMBB);
13156 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13182 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13183 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13187 bool is64bit = Subtarget.
isPPC64();
13189 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13194 Register oldval =
MI.getOperand(3).getReg();
13195 Register newval =
MI.getOperand(4).getReg();
13201 F->insert(It, loop1MBB);
13202 F->insert(It, loop2MBB);
13203 F->insert(It, exitMBB);
13210 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13229 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13261 if (ptrA != ZeroReg) {
13263 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13272 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13273 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13276 .
addImm(is8bit ? 28 : 27);
13277 if (!isLittleEndian)
13278 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13280 .
addImm(is8bit ? 24 : 16);
13282 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13287 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13292 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13295 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13302 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13306 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13309 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13312 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13317 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13334 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13358 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13383 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13391 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13392 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13393 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13394 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13395 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13396 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13399 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13400 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13404 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13408 .
addReg(
MI.getOperand(1).getReg())
13411 MI.getOperand(0).getReg())
13412 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13413 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13419 MI.getOperand(0).getReg())
13421 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13423 unsigned Imm =
MI.getOperand(1).getImm();
13426 MI.getOperand(0).getReg())
13428 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13430 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13433 if (
MRI.use_empty(OldFPSCRReg))
13434 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13436 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13447 unsigned Mode =
MI.getOperand(1).getImm();
13448 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13452 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13455 }
else if (
MI.getOpcode() == PPC::SETRND) {
13463 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13464 if (Subtarget.hasDirectMove()) {
13465 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13469 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13472 if (RC == &PPC::F8RCRegClass) {
13475 "Unsupported RegClass.");
13477 StoreOp = PPC::STFD;
13482 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13483 "Unsupported RegClass.");
13516 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13519 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13533 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13541 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13542 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13548 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13555 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13564 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13568 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13569 if (
MRI.use_empty(OldFPSCRReg))
13570 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13572 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13575 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13581 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13582 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13584 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13591 .
addUse(Src, 0, PPC::sub_gp8_x1);
13594 .
addUse(Src, 0, PPC::sub_gp8_x0);
13595 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13596 MI.getOpcode() == PPC::STQX_PSEUDO) {
13602 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13608 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13609 :
TII->get(PPC::STQ))
13617 MI.eraseFromParent();
13630 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
13633 return RefinementSteps;
13639 EVT VT =
Op.getValueType();
13642 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
13666PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
13669 EVT VT =
Op.getValueType();
13670 if (VT != MVT::f64 &&
13671 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
13678 int Enabled,
int &RefinementSteps,
13679 bool &UseOneConstNR,
13680 bool Reciprocal)
const {
13682 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
13683 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
13684 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13685 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13691 UseOneConstNR = !Subtarget.needsTwoConstNR();
13699 int &RefinementSteps)
const {
13701 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
13702 (VT == MVT::f64 && Subtarget.hasFRE()) ||
13703 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
13704 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
13712unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
13750 unsigned Bytes,
int Dist,
13760 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
13761 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
13764 if (FS != BFS || FS != (
int)Bytes)
return false;
13768 SDValue Base1 = Loc, Base2 = BaseLoc;
13769 int64_t Offset1 = 0, Offset2 = 0;
13772 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
13782 if (isGA1 && isGA2 && GV1 == GV2)
13783 return Offset1 == (Offset2 + Dist*Bytes);
13790 unsigned Bytes,
int Dist,
13793 EVT VT = LS->getMemoryVT();
13794 SDValue Loc = LS->getBasePtr();
13800 switch (
N->getConstantOperandVal(1)) {
13801 default:
return false;
13802 case Intrinsic::ppc_altivec_lvx:
13803 case Intrinsic::ppc_altivec_lvxl:
13804 case Intrinsic::ppc_vsx_lxvw4x:
13805 case Intrinsic::ppc_vsx_lxvw4x_be:
13808 case Intrinsic::ppc_vsx_lxvd2x:
13809 case Intrinsic::ppc_vsx_lxvd2x_be:
13812 case Intrinsic::ppc_altivec_lvebx:
13815 case Intrinsic::ppc_altivec_lvehx:
13818 case Intrinsic::ppc_altivec_lvewx:
13828 switch (
N->getConstantOperandVal(1)) {
13829 default:
return false;
13830 case Intrinsic::ppc_altivec_stvx:
13831 case Intrinsic::ppc_altivec_stvxl:
13832 case Intrinsic::ppc_vsx_stxvw4x:
13835 case Intrinsic::ppc_vsx_stxvd2x:
13838 case Intrinsic::ppc_vsx_stxvw4x_be:
13841 case Intrinsic::ppc_vsx_stxvd2x_be:
13844 case Intrinsic::ppc_altivec_stvebx:
13847 case Intrinsic::ppc_altivec_stvehx:
13850 case Intrinsic::ppc_altivec_stvewx:
13867 SDValue Chain = LD->getChain();
13868 EVT VT = LD->getMemoryVT();
13877 while (!Queue.empty()) {
13878 SDNode *ChainNext = Queue.pop_back_val();
13879 if (!Visited.
insert(ChainNext).second)
13882 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
13886 if (!Visited.
count(ChainLD->getChain().getNode()))
13887 Queue.push_back(ChainLD->getChain().getNode());
13889 for (
const SDUse &O : ChainNext->
ops())
13890 if (!Visited.
count(O.getNode()))
13891 Queue.push_back(O.getNode());
13893 LoadRoots.
insert(ChainNext);
13904 for (
SDNode *
I : LoadRoots) {
13905 Queue.push_back(
I);
13907 while (!Queue.empty()) {
13908 SDNode *LoadRoot = Queue.pop_back_val();
13909 if (!Visited.
insert(LoadRoot).second)
13912 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
13917 if (((isa<MemSDNode>(U) &&
13918 cast<MemSDNode>(U)->getChain().getNode() == LoadRoot) ||
13921 Queue.push_back(U);
13954 auto Final = Shifted;
13965 DAGCombinerInfo &DCI)
const {
13973 if (!DCI.isAfterLegalizeDAG())
13978 for (
const SDNode *U :
N->uses())
13983 auto OpSize =
N->getOperand(0).getValueSizeInBits();
13987 if (OpSize <
Size) {
14005 DAGCombinerInfo &DCI)
const {
14009 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14020 N->getValueType(0) != MVT::i1)
14023 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14024 N->getOperand(0).getValueType() != MVT::i64)
14032 cast<CondCodeSDNode>(
N->getOperand(
14034 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14045 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14068 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14069 N->getOperand(0).getOpcode() !=
ISD::OR &&
14070 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14080 N->getOperand(1).getOpcode() !=
ISD::AND &&
14081 N->getOperand(1).getOpcode() !=
ISD::OR &&
14082 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14095 for (
unsigned i = 0; i < 2; ++i) {
14099 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14100 isa<ConstantSDNode>(
N->getOperand(i)))
14111 while (!BinOps.
empty()) {
14119 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14153 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14154 if (isa<ConstantSDNode>(Inputs[i]))
14177 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14199 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14202 if (isa<ConstantSDNode>(Inputs[i]))
14208 std::list<HandleSDNode> PromOpHandles;
14209 for (
auto &PromOp : PromOps)
14210 PromOpHandles.emplace_back(PromOp);
14217 while (!PromOpHandles.empty()) {
14219 PromOpHandles.pop_back();
14225 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14228 PromOpHandles.emplace_front(PromOp);
14233 if (isa<ConstantSDNode>(RepValue))
14242 default:
C = 0;
break;
14247 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14255 PromOpHandles.emplace_front(PromOp);
14263 for (
unsigned i = 0; i < 2; ++i)
14264 if (isa<ConstantSDNode>(Ops[
C+i]))
14273 return N->getOperand(0);
14281 DAGCombinerInfo &DCI)
const {
14299 if (
N->getValueType(0) != MVT::i32 &&
14300 N->getValueType(0) != MVT::i64)
14303 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14304 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14307 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14308 N->getOperand(0).getOpcode() !=
ISD::OR &&
14309 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14320 while (!BinOps.
empty()) {
14328 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14359 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14360 if (isa<ConstantSDNode>(Inputs[i]))
14371 SelectTruncOp[0].
insert(std::make_pair(
User,
14375 SelectTruncOp[0].
insert(std::make_pair(
User,
14378 SelectTruncOp[1].
insert(std::make_pair(
User,
14384 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14393 SelectTruncOp[0].
insert(std::make_pair(
User,
14397 SelectTruncOp[0].
insert(std::make_pair(
User,
14400 SelectTruncOp[1].
insert(std::make_pair(
User,
14406 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14407 bool ReallyNeedsExt =
false;
14411 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14412 if (isa<ConstantSDNode>(Inputs[i]))
14416 Inputs[i].getOperand(0).getValueSizeInBits();
14417 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14422 OpBits-PromBits))) ||
14425 (OpBits-(PromBits-1)))) {
14426 ReallyNeedsExt =
true;
14434 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14438 if (isa<ConstantSDNode>(Inputs[i]))
14441 SDValue InSrc = Inputs[i].getOperand(0);
14455 std::list<HandleSDNode> PromOpHandles;
14456 for (
auto &PromOp : PromOps)
14457 PromOpHandles.emplace_back(PromOp);
14463 while (!PromOpHandles.empty()) {
14465 PromOpHandles.pop_back();
14469 default:
C = 0;
break;
14474 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14482 PromOpHandles.emplace_front(PromOp);
14492 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14494 PromOpHandles.emplace_front(PromOp);
14503 for (
unsigned i = 0; i < 2; ++i) {
14504 if (!isa<ConstantSDNode>(Ops[
C+i]))
14521 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14522 if (SI0 != SelectTruncOp[0].
end())
14524 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14525 if (SI1 != SelectTruncOp[1].
end())
14534 if (!ReallyNeedsExt)
14535 return N->getOperand(0);
14542 N->getValueSizeInBits(0), PromBits),
14543 dl,
N->getValueType(0)));
14546 "Invalid extension type");
14549 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14557 DAGCombinerInfo &DCI)
const {
14559 "Should be called with a SETCC node");
14577 EVT VT =
N->getValueType(0);
14578 EVT OpVT =
LHS.getValueType();
14584 return DAGCombineTruncBoolExt(
N, DCI);
14589 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14591 Op.getValueType() == MVT::f64;
14603combineElementTruncationToVectorTruncation(
SDNode *
N,
14604 DAGCombinerInfo &DCI)
const {
14606 "Should be called with a BUILD_VECTOR node");
14611 SDValue FirstInput =
N->getOperand(0);
14613 "The input operand must be an fp-to-int conversion.");
14622 bool IsSplat =
true;
14627 EVT TargetVT =
N->getValueType(0);
14628 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14629 SDValue NextOp =
N->getOperand(i);
14633 if (NextConversion != FirstConversion)
14641 if (
N->getOperand(i) != FirstInput)
14652 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
14653 SDValue In =
N->getOperand(i).getOperand(0);
14676 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
14678 return DAG.
getNode(Opcode, dl, TargetVT, BV);
14691 "Should be called with a BUILD_VECTOR node");
14696 if (!
N->getValueType(0).getVectorElementType().isByteSized())
14699 bool InputsAreConsecutiveLoads =
true;
14700 bool InputsAreReverseConsecutive =
true;
14701 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
14702 SDValue FirstInput =
N->getOperand(0);
14703 bool IsRoundOfExtLoad =
false;
14708 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
14713 N->getNumOperands() == 1)
14716 if (!IsRoundOfExtLoad)
14717 FirstLoad = cast<LoadSDNode>(FirstInput);
14721 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
14723 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
14726 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
14732 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
14733 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
14734 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
14743 InputsAreConsecutiveLoads =
false;
14745 InputsAreReverseConsecutive =
false;
14748 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
14753 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
14754 "The loads cannot be both consecutive and reverse consecutive.");
14758 if (InputsAreConsecutiveLoads) {
14759 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
14763 ReturnSDVal = WideLoad;
14764 }
else if (InputsAreReverseConsecutive) {
14766 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
14771 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
14775 DAG.
getUNDEF(
N->getValueType(0)), Ops);
14779 for (
auto *LD : InputLoads)
14781 return ReturnSDVal;
14798 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14800 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
14802 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
14803 CorrectElems = CorrectElems >> 8;
14804 Elems = Elems >> 8;
14811 EVT VT =
N->getValueType(0);
14849 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
14869 if (Input && Input != Extract.
getOperand(0))
14875 Elems = Elems << 8;
14884 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
14885 if (!isSExtOfVecExtract(
N->getOperand(i))) {
14892 int TgtElemArrayIdx;
14894 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
14895 if (InputSize + OutputSize == 40)
14896 TgtElemArrayIdx = 0;
14897 else if (InputSize + OutputSize == 72)
14898 TgtElemArrayIdx = 1;
14899 else if (InputSize + OutputSize == 48)
14900 TgtElemArrayIdx = 2;
14901 else if (InputSize + OutputSize == 80)
14902 TgtElemArrayIdx = 3;
14903 else if (InputSize + OutputSize == 96)
14904 TgtElemArrayIdx = 4;
14908 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
14910 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
14911 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
14912 if (Elems != CorrectElems) {
14928 if (
N->getValueType(0) != MVT::v1i128)
14931 SDValue Operand =
N->getOperand(0);
14937 auto *LD = cast<LoadSDNode>(Operand);
14938 EVT MemoryType = LD->getMemoryVT();
14942 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
14943 MemoryType == MVT::i32 || MemoryType == MVT::i64;
14946 if (!ValidLDType ||
14952 LD->getChain(), LD->getBasePtr(),
14956 DAG.
getVTList(MVT::v1i128, MVT::Other),
14957 LoadOps, MemoryType, LD->getMemOperand());
14961 DAGCombinerInfo &DCI)
const {
14963 "Should be called with a BUILD_VECTOR node");
14968 if (!Subtarget.hasVSX())
14974 SDValue FirstInput =
N->getOperand(0);
14976 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
14991 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15000 if (Subtarget.isISA3_1()) {
15006 if (
N->getValueType(0) != MVT::v2f64)
15017 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15021 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15028 if (!Ext1Op || !Ext2Op)
15037 if (FirstElem == 0 && SecondElem == 1)
15039 else if (FirstElem == 2 && SecondElem == 3)
15047 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15052 DAGCombinerInfo &DCI)
const {
15055 "Need an int -> FP conversion node here");
15066 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15068 if (!
Op.getOperand(0).getValueType().isSimple())
15070 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15071 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15074 SDValue FirstOperand(
Op.getOperand(0));
15075 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15076 (FirstOperand.getValueType() == MVT::i8 ||
15077 FirstOperand.getValueType() == MVT::i16);
15078 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15080 bool DstDouble =
Op.getValueType() == MVT::f64;
15081 unsigned ConvOp =
Signed ?
15087 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15096 SDValue ExtOps[] = { Ld, WidthConst };
15098 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15100 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15108 if (
Op.getOperand(0).getValueType() == MVT::i32)
15112 "UINT_TO_FP is supported only with FPCVT");
15116 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15121 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15128 Subtarget.hasFPCVT()) ||
15130 SDValue Src =
Op.getOperand(0).getOperand(0);
15131 if (Src.getValueType() == MVT::f32) {
15133 DCI.AddToWorklist(Src.getNode());
15134 }
else if (Src.getValueType() != MVT::f64) {
15146 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15149 DCI.AddToWorklist(
FP.getNode());
15173 switch (
N->getOpcode()) {
15178 Chain = LD->getChain();
15179 Base = LD->getBasePtr();
15180 MMO = LD->getMemOperand();
15199 MVT VecTy =
N->getValueType(0).getSimpleVT();
15207 Chain = Load.getValue(1);
15213 if (VecTy != MVT::v2f64) {
15240 switch (
N->getOpcode()) {
15245 Chain = ST->getChain();
15246 Base = ST->getBasePtr();
15247 MMO = ST->getMemOperand();
15267 SDValue Src =
N->getOperand(SrcOpnd);
15268 MVT VecTy = Src.getValueType().getSimpleVT();
15271 if (VecTy != MVT::v2f64) {
15277 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15283 StoreOps, VecTy, MMO);
15290 DAGCombinerInfo &DCI)
const {
15293 unsigned Opcode =
N->getOperand(1).getOpcode();
15295 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15299 &&
"Not a FP_TO_INT Instruction!");
15301 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15302 EVT Op1VT =
N->getOperand(1).getValueType();
15305 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15309 bool ValidTypeForStoreFltAsInt =
15310 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15311 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15314 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15317 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15318 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15325 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15331 cast<StoreSDNode>(
N)->getMemoryVT(),
15332 cast<StoreSDNode>(
N)->getMemOperand());
15340 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15341 for (
int i = 1, e = Mask.size(); i < e; i++) {
15342 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15344 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15346 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15358 FirstOp =
Op.getOperand(i);
15365 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15375 Op =
Op.getOperand(0);
15390 int LHSMaxIdx,
int RHSMinIdx,
15391 int RHSMaxIdx,
int HalfVec,
15392 unsigned ValidLaneWidth,
15394 for (
int i = 0, e = ShuffV.
size(); i < e; i++) {
15395 int Idx = ShuffV[i];
15396 if ((
Idx >= 0 &&
Idx < LHSMaxIdx) || (
Idx >= RHSMinIdx &&
Idx < RHSMaxIdx))
15398 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - ValidLaneWidth;
15409 SDLoc dl(OrigSToV);
15412 "Expecting a SCALAR_TO_VECTOR here");
15425 "Cannot produce a permuted scalar_to_vector for one element vector");
15427 unsigned ResultInElt = NumElts / 2;
15429 NewMask[ResultInElt] =
Idx->getZExtValue();
15454 int NumElts =
LHS.getValueType().getVectorNumElements();
15464 if (!Subtarget.hasDirectMove())
15474 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15483 if (SToVLHS || SToVRHS) {
15490 if (SToVLHS && SToVRHS &&
15497 int NumEltsOut = ShuffV.
size();
15502 unsigned ValidLaneWidth =
15504 LHS.getValueType().getScalarSizeInBits()
15506 RHS.getValueType().getScalarSizeInBits();
15510 int LHSMaxIdx = -1;
15511 int RHSMinIdx = -1;
15512 int RHSMaxIdx = -1;
15513 int HalfVec =
LHS.getValueType().getVectorNumElements() / 2;
15525 LHSMaxIdx = NumEltsOut / NumEltsIn;
15534 RHSMinIdx = NumEltsOut;
15535 RHSMaxIdx = NumEltsOut / NumEltsIn + RHSMinIdx;
15548 HalfVec, ValidLaneWidth, Subtarget);
15553 if (!isa<ShuffleVectorSDNode>(Res))
15555 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15574 if (IsLittleEndian) {
15577 if (Mask[0] < NumElts)
15578 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15582 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
15587 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15591 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
15596 if (Mask[0] < NumElts)
15597 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
15601 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
15606 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
15610 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
15617 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
15620 if (IsLittleEndian)
15629 DAGCombinerInfo &DCI)
const {
15631 "Not a reverse memop pattern!");
15636 auto I =
Mask.rbegin();
15637 auto E =
Mask.rend();
15639 for (;
I != E; ++
I) {
15656 if (!Subtarget.hasP9Vector())
15659 if(!IsElementReverse(SVN))
15698 if (IntrinsicID == Intrinsic::ppc_stdcx)
15700 else if (IntrinsicID == Intrinsic::ppc_stwcx)
15702 else if (IntrinsicID == Intrinsic::ppc_sthcx)
15704 else if (IntrinsicID == Intrinsic::ppc_stbcx)
15715 switch (
N->getOpcode()) {
15718 return combineADD(
N, DCI);
15727 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
15737 if (!isUInt<32>(Imm))
15744 return combineSHL(
N, DCI);
15746 return combineSRA(
N, DCI);
15748 return combineSRL(
N, DCI);
15750 return combineMUL(
N, DCI);
15753 return combineFMALike(
N, DCI);
15756 return N->getOperand(0);
15760 return N->getOperand(0);
15766 return N->getOperand(0);
15772 return DAGCombineExtBoolTrunc(
N, DCI);
15774 return combineTRUNCATE(
N, DCI);
15776 if (
SDValue CSCC = combineSetCC(
N, DCI))
15780 return DAGCombineTruncBoolExt(
N, DCI);
15783 return combineFPToIntToFP(
N, DCI);
15786 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
15787 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
15789 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
15792 EVT Op1VT =
N->getOperand(1).getValueType();
15793 unsigned Opcode =
N->getOperand(1).getOpcode();
15797 SDValue Val = combineStoreFPToInt(
N, DCI);
15804 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
15810 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
15811 N->getOperand(1).getNode()->hasOneUse() &&
15812 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
15813 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
15817 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
15821 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
15828 if (Op1VT.
bitsGT(mVT)) {
15833 if (Op1VT == MVT::i64)
15838 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
15842 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
15843 cast<StoreSDNode>(
N)->getMemOperand());
15849 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
15851 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
15861 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
15870 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
15871 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
15878 EVT VT = LD->getValueType(0);
15885 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
15886 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
15897 auto ReplaceTwoFloatLoad = [&]() {
15898 if (VT != MVT::i64)
15913 if (!LD->hasNUsesOfValue(2, 0))
15916 auto UI = LD->use_begin();
15917 while (UI.getUse().getResNo() != 0) ++UI;
15919 while (UI.getUse().getResNo() != 0) ++UI;
15920 SDNode *RightShift = *UI;
15928 if (RightShift->getOpcode() !=
ISD::SRL ||
15929 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
15930 RightShift->getConstantOperandVal(1) != 32 ||
15931 !RightShift->hasOneUse())
15934 SDNode *Trunc2 = *RightShift->use_begin();
15944 Bitcast->getValueType(0) != MVT::f32)
15956 SDValue BasePtr = LD->getBasePtr();
15957 if (LD->isIndexed()) {
15959 "Non-pre-inc AM on PPC?");
15967 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
15968 LD->getPointerInfo(), LD->getAlign(),
15969 MMOFlags, LD->getAAInfo());
15975 LD->getPointerInfo().getWithOffset(4),
15978 if (LD->isIndexed()) {
15992 if (ReplaceTwoFloatLoad())
15995 EVT MemVT = LD->getMemoryVT();
15998 if (LD->isUnindexed() && VT.
isVector() &&
16001 !Subtarget.hasP8Vector() &&
16002 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16003 VT == MVT::v4f32))) &&
16004 LD->getAlign() < ABIAlignment) {
16006 SDValue Chain = LD->getChain();
16035 MVT PermCntlTy, PermTy, LDTy;
16036 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16037 : Intrinsic::ppc_altivec_lvsl;
16038 IntrLD = Intrinsic::ppc_altivec_lvx;
16039 IntrPerm = Intrinsic::ppc_altivec_vperm;
16040 PermCntlTy = MVT::v16i8;
16041 PermTy = MVT::v4i32;
16060 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16064 BaseLoadOps, LDTy, BaseMMO);
16073 int IncValue = IncOffset;
16090 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16094 ExtraLoadOps, LDTy, ExtraMMO);
16105 if (isLittleEndian)
16107 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16110 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16113 Perm = Subtarget.hasAltivec()
16129 unsigned IID =
N->getConstantOperandVal(0);
16131 : Intrinsic::ppc_altivec_lvsl);
16132 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16139 .
zext(
Add.getScalarValueSizeInBits()))) {
16140 SDNode *BasePtr =
Add->getOperand(0).getNode();
16141 for (
SDNode *U : BasePtr->uses()) {
16143 U->getConstantOperandVal(0) == IID) {
16153 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16154 SDNode *BasePtr =
Add->getOperand(0).getNode();
16155 for (
SDNode *U : BasePtr->uses()) {
16157 isa<ConstantSDNode>(U->getOperand(1)) &&
16158 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16164 V->getConstantOperandVal(0) == IID) {
16176 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16177 IID == Intrinsic::ppc_altivec_vmaxsh ||
16178 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16194 V2.getOperand(1) == V1) {
16209 switch (
N->getConstantOperandVal(1)) {
16212 case Intrinsic::ppc_altivec_vsum4sbs:
16213 case Intrinsic::ppc_altivec_vsum4shs:
16214 case Intrinsic::ppc_altivec_vsum4ubs: {
16220 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16221 APInt APSplatBits, APSplatUndef;
16222 unsigned SplatBitSize;
16225 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16228 if (BVNIsConstantSplat && APSplatBits == 0)
16233 case Intrinsic::ppc_vsx_lxvw4x:
16234 case Intrinsic::ppc_vsx_lxvd2x:
16246 switch (
N->getConstantOperandVal(1)) {
16249 case Intrinsic::ppc_vsx_stxvw4x:
16250 case Intrinsic::ppc_vsx_stxvd2x:
16259 bool Is64BitBswapOn64BitTgt =
16260 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16262 N->getOperand(0).hasOneUse();
16263 if (IsSingleUseNormalLd &&
16264 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16265 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16276 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16277 MVT::i64 : MVT::i32, MVT::Other),
16278 Ops, LD->getMemoryVT(), LD->getMemOperand());
16282 if (
N->getValueType(0) == MVT::i16)
16299 !IsSingleUseNormalLd)
16301 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16304 if (!LD->isSimple())
16306 SDValue BasePtr = LD->getBasePtr();
16308 LD->getPointerInfo(), LD->getAlign());
16313 LD->getMemOperand(), 4, 4);
16323 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16332 if (!
N->getOperand(0).hasOneUse() &&
16333 !
N->getOperand(1).hasOneUse() &&
16334 !
N->getOperand(2).hasOneUse()) {
16337 SDNode *VCMPrecNode =
nullptr;
16339 SDNode *LHSN =
N->getOperand(0).getNode();
16343 UI->getOperand(1) ==
N->getOperand(1) &&
16344 UI->getOperand(2) ==
N->getOperand(2) &&
16345 UI->getOperand(0) ==
N->getOperand(0)) {
16358 SDNode *FlagUser =
nullptr;
16360 FlagUser ==
nullptr; ++UI) {
16361 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16374 return SDValue(VCMPrecNode, 0);
16396 auto RHSAPInt =
RHS->getAsAPIntVal();
16397 if (!RHSAPInt.isIntN(64))
16400 unsigned Val = RHSAPInt.getZExtValue();
16401 auto isImpossibleCompare = [&]() {
16404 if (Val != 0 && Val != 1) {
16406 return N->getOperand(0);
16409 N->getOperand(0),
N->getOperand(4));
16414 unsigned StoreWidth = 0;
16417 if (
SDValue Impossible = isImpossibleCompare())
16431 auto *MemNode = cast<MemSDNode>(
LHS);
16434 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16435 MemNode->getMemoryVT(), MemNode->getMemOperand());
16439 if (
N->getOperand(0) ==
LHS.getValue(1))
16440 InChain =
LHS.getOperand(0);
16452 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16458 assert(isDot &&
"Can't compare against a vector result!");
16460 if (
SDValue Impossible = isImpossibleCompare())
16463 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16470 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16475 switch (
LHS.getConstantOperandVal(1)) {
16494 N->getOperand(4), CompNode.
getValue(1));
16499 return DAGCombineBuildVector(
N, DCI);
16510 EVT VT =
N->getValueType(0);
16511 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16513 if ((VT != MVT::i32 && VT != MVT::i64) ||
16521 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16541 const APInt &DemandedElts,
16543 unsigned Depth)
const {
16545 switch (
Op.getOpcode()) {
16549 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16550 Known.
Zero = 0xFFFF0000;
16554 switch (
Op.getConstantOperandVal(0)) {
16556 case Intrinsic::ppc_altivec_vcmpbfp_p:
16557 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16558 case Intrinsic::ppc_altivec_vcmpequb_p:
16559 case Intrinsic::ppc_altivec_vcmpequh_p:
16560 case Intrinsic::ppc_altivec_vcmpequw_p:
16561 case Intrinsic::ppc_altivec_vcmpequd_p:
16562 case Intrinsic::ppc_altivec_vcmpequq_p:
16563 case Intrinsic::ppc_altivec_vcmpgefp_p:
16564 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16565 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16566 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16567 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16568 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16569 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16570 case Intrinsic::ppc_altivec_vcmpgtub_p:
16571 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16572 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16573 case Intrinsic::ppc_altivec_vcmpgtud_p:
16574 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16581 switch (
Op.getConstantOperandVal(1)) {
16584 case Intrinsic::ppc_load2r:
16586 Known.
Zero = 0xFFFF0000;
16616 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
16625 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
16627 LoopSize +=
TII->getInstSizeInBytes(J);
16632 if (LoopSize > 16 && LoopSize <= 32)
16646 if (Constraint.
size() == 1) {
16647 switch (Constraint[0]) {
16665 }
else if (Constraint ==
"wc") {
16667 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
16668 Constraint ==
"wf" || Constraint ==
"ws" ||
16669 Constraint ==
"wi" || Constraint ==
"ww") {
16682 Value *CallOperandVal =
info.CallOperandVal;
16685 if (!CallOperandVal)
16692 else if ((
StringRef(constraint) ==
"wa" ||
16704 switch (*constraint) {
16734std::pair<unsigned, const TargetRegisterClass *>
16738 if (Constraint.
size() == 1) {
16740 switch (Constraint[0]) {
16742 if (VT == MVT::i64 && Subtarget.
isPPC64())
16743 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
16744 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
16746 if (VT == MVT::i64 && Subtarget.
isPPC64())
16747 return std::make_pair(0U, &PPC::G8RCRegClass);
16748 return std::make_pair(0U, &PPC::GPRCRegClass);
16754 if (Subtarget.hasSPE()) {
16755 if (VT == MVT::f32 || VT == MVT::i32)
16756 return std::make_pair(0U, &PPC::GPRCRegClass);
16757 if (VT == MVT::f64 || VT == MVT::i64)
16758 return std::make_pair(0U, &PPC::SPERCRegClass);
16760 if (VT == MVT::f32 || VT == MVT::i32)
16761 return std::make_pair(0U, &PPC::F4RCRegClass);
16762 if (VT == MVT::f64 || VT == MVT::i64)
16763 return std::make_pair(0U, &PPC::F8RCRegClass);
16767 if (Subtarget.hasAltivec() && VT.
isVector())
16768 return std::make_pair(0U, &PPC::VRRCRegClass);
16769 else if (Subtarget.hasVSX())
16771 return std::make_pair(0U, &PPC::VFRCRegClass);
16774 return std::make_pair(0U, &PPC::CRRCRegClass);
16776 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
16778 return std::make_pair(0U, &PPC::CRBITRCRegClass);
16779 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
16780 Constraint ==
"wf" || Constraint ==
"wi") &&
16781 Subtarget.hasVSX()) {
16785 return std::make_pair(0U, &PPC::VSRCRegClass);
16786 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16787 return std::make_pair(0U, &PPC::VSSRCRegClass);
16788 return std::make_pair(0U, &PPC::VSFRCRegClass);
16789 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
16790 if (VT == MVT::f32 && Subtarget.hasP8Vector())
16791 return std::make_pair(0U, &PPC::VSSRCRegClass);
16793 return std::make_pair(0U, &PPC::VSFRCRegClass);
16794 }
else if (Constraint ==
"lr") {
16795 if (VT == MVT::i64)
16796 return std::make_pair(0U, &PPC::LR8RCRegClass);
16798 return std::make_pair(0U, &PPC::LRRCRegClass);
16803 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
16807 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
16808 int VSNum = atoi(Constraint.
data() + 3);
16809 assert(VSNum >= 0 && VSNum <= 63 &&
16810 "Attempted to access a vsr out of range");
16812 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
16813 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
16818 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
16819 int RegNum = atoi(Constraint.
data() + 2);
16820 if (RegNum > 31 || RegNum < 0)
16822 if (VT == MVT::f32 || VT == MVT::i32)
16823 return Subtarget.hasSPE()
16824 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
16825 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
16826 if (VT == MVT::f64 || VT == MVT::i64)
16827 return Subtarget.hasSPE()
16828 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
16829 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
16833 std::pair<unsigned, const TargetRegisterClass *> R =
16842 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
16843 PPC::GPRCRegClass.contains(R.first))
16844 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
16845 PPC::sub_32, &PPC::G8RCRegClass),
16846 &PPC::G8RCRegClass);
16849 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
16850 R.first = PPC::CR0;
16851 R.second = &PPC::CRRCRegClass;
16855 if (Subtarget.
isAIXABI() && !
TM.getAIXExtendedAltivecABI()) {
16856 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
16857 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
16858 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
16859 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
16860 "default AIX AltiVec ABI and cannot be used\n";
16870 std::vector<SDValue> &Ops,
16875 if (Constraint.
size() > 1)
16878 char Letter = Constraint[0];
16893 EVT TCVT = MVT::i64;
16898 if (isInt<16>(
Value))
16902 if (isShiftedUInt<16, 16>(
Value))
16906 if (isShiftedInt<16, 16>(
Value))
16910 if (isUInt<16>(
Value))
16926 if (isInt<16>(-
Value))
16934 if (Result.getNode()) {
16935 Ops.push_back(Result);
16946 if (
I.getNumOperands() <= 1)
16948 if (!isa<ConstantSDNode>(Ops[1].getNode()))
16950 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
16951 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
16952 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
16955 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
16983 switch (AM.
Scale) {
17014 unsigned Depth =
Op.getConstantOperandVal(0);
17020 bool isPPC64 = Subtarget.
isPPC64();
17032 isPPC64 ? MVT::i64 : MVT::i32);
17039 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17047 unsigned Depth =
Op.getConstantOperandVal(0);
17054 bool isPPC64 = PtrVT == MVT::i64;
17060 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17062 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17076 bool isPPC64 = Subtarget.
isPPC64();
17110 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17128 unsigned Intrinsic)
const {
17129 switch (Intrinsic) {
17130 case Intrinsic::ppc_atomicrmw_xchg_i128:
17131 case Intrinsic::ppc_atomicrmw_add_i128:
17132 case Intrinsic::ppc_atomicrmw_sub_i128:
17133 case Intrinsic::ppc_atomicrmw_nand_i128:
17134 case Intrinsic::ppc_atomicrmw_and_i128:
17135 case Intrinsic::ppc_atomicrmw_or_i128:
17136 case Intrinsic::ppc_atomicrmw_xor_i128:
17137 case Intrinsic::ppc_cmpxchg_i128:
17139 Info.memVT = MVT::i128;
17140 Info.ptrVal =
I.getArgOperand(0);
17146 case Intrinsic::ppc_atomic_load_i128:
17148 Info.memVT = MVT::i128;
17149 Info.ptrVal =
I.getArgOperand(0);
17154 case Intrinsic::ppc_atomic_store_i128:
17156 Info.memVT = MVT::i128;
17157 Info.ptrVal =
I.getArgOperand(2);
17162 case Intrinsic::ppc_altivec_lvx:
17163 case Intrinsic::ppc_altivec_lvxl:
17164 case Intrinsic::ppc_altivec_lvebx:
17165 case Intrinsic::ppc_altivec_lvehx:
17166 case Intrinsic::ppc_altivec_lvewx:
17167 case Intrinsic::ppc_vsx_lxvd2x:
17168 case Intrinsic::ppc_vsx_lxvw4x:
17169 case Intrinsic::ppc_vsx_lxvd2x_be:
17170 case Intrinsic::ppc_vsx_lxvw4x_be:
17171 case Intrinsic::ppc_vsx_lxvl:
17172 case Intrinsic::ppc_vsx_lxvll: {
17174 switch (Intrinsic) {
17175 case Intrinsic::ppc_altivec_lvebx:
17178 case Intrinsic::ppc_altivec_lvehx:
17181 case Intrinsic::ppc_altivec_lvewx:
17184 case Intrinsic::ppc_vsx_lxvd2x:
17185 case Intrinsic::ppc_vsx_lxvd2x_be:
17195 Info.ptrVal =
I.getArgOperand(0);
17202 case Intrinsic::ppc_altivec_stvx:
17203 case Intrinsic::ppc_altivec_stvxl:
17204 case Intrinsic::ppc_altivec_stvebx:
17205 case Intrinsic::ppc_altivec_stvehx:
17206 case Intrinsic::ppc_altivec_stvewx:
17207 case Intrinsic::ppc_vsx_stxvd2x:
17208 case Intrinsic::ppc_vsx_stxvw4x:
17209 case Intrinsic::ppc_vsx_stxvd2x_be:
17210 case Intrinsic::ppc_vsx_stxvw4x_be:
17211 case Intrinsic::ppc_vsx_stxvl:
17212 case Intrinsic::ppc_vsx_stxvll: {
17214 switch (Intrinsic) {
17215 case Intrinsic::ppc_altivec_stvebx:
17218 case Intrinsic::ppc_altivec_stvehx:
17221 case Intrinsic::ppc_altivec_stvewx:
17224 case Intrinsic::ppc_vsx_stxvd2x:
17225 case Intrinsic::ppc_vsx_stxvd2x_be:
17235 Info.ptrVal =
I.getArgOperand(1);
17242 case Intrinsic::ppc_stdcx:
17243 case Intrinsic::ppc_stwcx:
17244 case Intrinsic::ppc_sthcx:
17245 case Intrinsic::ppc_stbcx: {
17247 auto Alignment =
Align(8);
17248 switch (Intrinsic) {
17249 case Intrinsic::ppc_stdcx:
17252 case Intrinsic::ppc_stwcx:
17254 Alignment =
Align(4);
17256 case Intrinsic::ppc_sthcx:
17258 Alignment =
Align(2);
17260 case Intrinsic::ppc_stbcx:
17262 Alignment =
Align(1);
17267 Info.ptrVal =
I.getArgOperand(0);
17269 Info.align = Alignment;
17287 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17288 if (
Op.isMemset() && Subtarget.hasVSX()) {
17293 if (TailSize > 2 && TailSize <= 4) {
17298 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17317 return !(BitSize == 0 || BitSize > 64);
17325 return NumBits1 == 64 && NumBits2 == 32;
17333 return NumBits1 == 64 && NumBits2 == 32;
17339 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17340 EVT MemVT = LD->getMemoryVT();
17341 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17342 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17358 "invalid fpext types");
17360 if (DestVT == MVT::f128)
17366 return isInt<16>(Imm) || isUInt<16>(Imm);
17370 return isInt<16>(Imm) || isUInt<16>(Imm);
17375 unsigned *
Fast)
const {
17389 !Subtarget.allowsUnalignedFPAccess())
17393 if (Subtarget.hasVSX()) {
17394 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17395 VT != MVT::v4f32 && VT != MVT::v4i32)
17402 if (VT == MVT::ppcf128)
17416 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17417 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17425 int64_t Imm = ConstNode->getSExtValue();
17426 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17428 if (isInt<16>(Imm))
17453 return Subtarget.hasP9Vector();
17461 if (!
I->hasOneUse())
17465 assert(
User &&
"A single use instruction with no uses.");
17467 switch (
I->getOpcode()) {
17468 case Instruction::FMul: {
17470 if (
User->getOpcode() != Instruction::FSub &&
17471 User->getOpcode() != Instruction::FAdd)
17484 case Instruction::Load: {
17497 if (
User->getOpcode() != Instruction::Store)
17517 static const MCPhysReg ScratchRegs[] = {
17518 PPC::X12, PPC::LR8, PPC::CTR8, 0
17521 return ScratchRegs;
17525 const Constant *PersonalityFn)
const {
17526 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17530 const Constant *PersonalityFn)
const {
17531 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17536 EVT VT ,
unsigned DefinedValues)
const {
17537 if (VT == MVT::v2i64)
17538 return Subtarget.hasDirectMove();
17540 if (Subtarget.hasVSX())
17574 bool LegalOps,
bool OptForSize,
17576 unsigned Depth)
const {
17580 unsigned Opc =
Op.getOpcode();
17581 EVT VT =
Op.getValueType();
17606 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
17610 N0Cost,
Depth + 1);
17614 N1Cost,
Depth + 1);
17616 if (NegN0 && N0Cost <= N1Cost) {
17617 Cost = std::min(N0Cost, N2Cost);
17618 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
17619 }
else if (NegN1) {
17620 Cost = std::min(N1Cost, N2Cost);
17621 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
17664 bool ForCodeSize)
const {
17665 if (!VT.
isSimple() || !Subtarget.hasVSX())
17675 if (Subtarget.hasPrefixInstrs()) {
17680 APSInt IntResult(16,
false);
17685 if (IsExact && IntResult <= 15 && IntResult >= -16)
17687 return Imm.isZero();
17690 return Imm.isPosZero();
17702 unsigned Opcode =
N->getOpcode();
17703 unsigned TargetOpcode;
17722 if (Mask->getZExtValue() == OpSizeInBits - 1)
17728SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17734 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
17737 N->getValueType(0) != MVT::i64)
17752 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
17758SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17765SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17784 auto isZextOfCompareWithConstant = [](
SDValue Op) {
17786 Op.getValueType() != MVT::i64)
17790 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
17791 Cmp.getOperand(0).getValueType() != MVT::i64)
17794 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
17795 int64_t NegConstant = 0 -
Constant->getSExtValue();
17798 return isInt<16>(NegConstant);
17804 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
17805 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
17808 if (LHSHasPattern && !RHSHasPattern)
17810 else if (!LHSHasPattern && !RHSHasPattern)
17816 SDValue Z = Cmp.getOperand(0);
17817 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
17818 int64_t NegConstant = 0 -
Constant->getSExtValue();
17820 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
17831 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17846 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
17883 if (!GSDN || !ConstNode)
17890 if (!isInt<34>(NewOffset))
17903SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17923 DAGCombinerInfo &DCI)
const {
17925 if (Subtarget.useCRBits()) {
17927 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
17928 return CRTruncValue;
17935 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
17938 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
17948 EltToExtract = EltToExtract ? 0 : 1;
17958 return DCI.DAG.getNode(
17960 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
17965SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
17969 if (!ConstOpOrElement)
17977 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18000 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18004 EVT VT =
N->getValueType(0);
18011 if ((MulAmtAbs - 1).isPowerOf2()) {
18015 if (!IsProfitable(IsNeg,
true, VT))
18028 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18032 if (!IsProfitable(IsNeg,
false, VT))
18053 DAGCombinerInfo &DCI)
const {
18058 EVT VT =
N->getValueType(0);
18061 unsigned Opc =
N->getOpcode();
18063 bool LegalOps = !DCI.isBeforeLegalizeOps();
18071 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18087bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18104 if (!Callee ||
Callee->isVarArg())
18117bool PPCTargetLowering::
18118isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18121 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18123 if (CI->getBitWidth() > 64)
18125 int64_t ConstVal = CI->getZExtValue();
18126 return isUInt<16>(ConstVal) ||
18127 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18136PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18142 if ((Flags & FlagSet) == FlagSet)
18145 if ((Flags & FlagSet) == FlagSet)
18148 if ((Flags & FlagSet) == FlagSet)
18151 if ((Flags & FlagSet) == FlagSet)
18172 if ((FrameIndexAlign % 4) != 0)
18173 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18174 if ((FrameIndexAlign % 16) != 0)
18175 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18179 if ((FrameIndexAlign % 4) == 0)
18181 if ((FrameIndexAlign % 16) == 0)
18194 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18195 if ((Imm & 0x3) == 0)
18197 if ((Imm & 0xf) == 0)
18203 const APInt &ConstImm = CN->getAPIntValue();
18222 const APInt &ConstImm = CN->getAPIntValue();
18232 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18244 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18245 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18246 isValidPCRelNode<JumpTableSDNode>(
N) ||
18247 isValidPCRelNode<BlockAddressSDNode>(
N));
18252unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18257 if (!Subtarget.hasP9Vector())
18261 if (Subtarget.hasPrefixInstrs())
18264 if (Subtarget.hasSPE())
18273 unsigned ParentOp = Parent->
getOpcode();
18277 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18278 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18289 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18290 if (LSB->isIndexed())
18295 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18296 assert(MN &&
"Parent should be a MemSDNode!");
18301 "Not expecting scalar integers larger than 16 bytes!");
18304 else if (
Size == 32)
18311 else if (
Size == 256) {
18312 assert(Subtarget.pairedVectorMemops() &&
18313 "256-bit vectors are only available when paired vector memops is "
18321 else if (MemVT == MVT::f128 || MemVT.
isVector())
18331 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18352 FlagSet &= ~PPC::MOF_NoExt;
18357 bool IsNonP1034BitConst =
18361 IsNonP1034BitConst)
18374 int16_t ForceXFormImm = 0;
18377 Disp =
N.getOperand(0);
18378 Base =
N.getOperand(1);
18389 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18390 Disp =
N.getOperand(0);
18391 Base =
N.getOperand(1);
18405 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18411 if (PartVT == MVT::f64 &&
18412 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18421SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18425 EVT RetVT =
Op.getValueType();
18433 EVT ArgVT =
N.getValueType();
18438 Entry.IsZExt = !Entry.IsSExt;
18439 Args.push_back(Entry);
18447 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18453 .setTailCall(isTailCall)
18460SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18461 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18463 if (
Op.getValueType() == MVT::f32)
18464 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18466 if (
Op.getValueType() == MVT::f64)
18467 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18472bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18474 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18478bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18479 return Op.getNode()->getFlags().hasApproximateFuncs();
18482bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18486SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18487 const char *LibCallFloatName,
18488 const char *LibCallDoubleNameFinite,
18489 const char *LibCallFloatNameFinite,
18492 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18495 if (!isLowringToMASSFiniteSafe(
Op))
18496 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18499 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18500 LibCallDoubleNameFinite,
Op, DAG);
18504 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18505 "__xl_powf_finite",
Op, DAG);
18509 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18510 "__xl_sinf_finite",
Op, DAG);
18514 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18515 "__xl_cosf_finite",
Op, DAG);
18519 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18520 "__xl_logf_finite",
Op, DAG);
18524 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18525 "__xl_log10f_finite",
Op, DAG);
18529 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18530 "__xl_expf_finite",
Op, DAG);
18537 if (!isa<FrameIndexSDNode>(
N))
18555 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18567 "Must be using PC-Relative calls when a valid PC-Relative node is "
18597 Disp =
N.getOperand(1).getOperand(0);
18602 Base =
N.getOperand(0);
18609 auto *CN = cast<ConstantSDNode>(
N);
18610 EVT CNType = CN->getValueType(0);
18611 uint64_t CNImm = CN->getZExtValue();
18622 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
18624 int32_t
Addr = (int32_t)CNImm;
18629 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
18645 unsigned Opcode =
N.getOpcode();
18653 Base =
N.getOperand(0);
18672 Base = FI ?
N :
N.getOperand(1);
18684 bool IsVarArg)
const {
18694 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
18728 return Intrinsic::ppc_atomicrmw_xchg_i128;
18730 return Intrinsic::ppc_atomicrmw_add_i128;
18732 return Intrinsic::ppc_atomicrmw_sub_i128;
18734 return Intrinsic::ppc_atomicrmw_and_i128;
18736 return Intrinsic::ppc_atomicrmw_or_i128;
18738 return Intrinsic::ppc_atomicrmw_xor_i128;
18740 return Intrinsic::ppc_atomicrmw_nand_i128;
18757 Value *LoHi = Builder.
CreateCall(RMW, {AlignedAddr, IncrLo, IncrHi});
18763 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
18784 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
18791 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
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)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
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...
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.
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 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 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
pre isel intrinsic Pre ISel Intrinsic Lowering
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
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.
This defines the Use class.
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.
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).
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
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.
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)
const BasicBlock * getParent() const
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.
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.
MachineModuleInfo & getMMI() const
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,.
const MCContext & getContext() const
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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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)
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
void setTailCallSPDelta(int size)
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 getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS)
Helper function to make it easier to build Select's if you just have operands and don't want to check...
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 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.
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
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.
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?...
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.
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL, bool LegalTypes=true) const
Returns the type for the shift amount of a shift opcode.
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.
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 minimum or maximum 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)
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)