68#include "llvm/IR/IntrinsicsPowerPC.h"
102#define DEBUG_TYPE "ppc-lowering"
105 "disable-p10-store-forward",
129 cl::desc(
"disable vector permute decomposition"),
133 "disable-auto-paired-vec-st",
134 cl::desc(
"disable automatically generated 32byte paired vector stores"),
139 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
143 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
147 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
148 "function to use initial-exec"));
153 "Number of shuffles lowered to a VPERM or XXPERM");
154STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
175 initializeAddrModeMap();
178 bool isPPC64 = Subtarget.isPPC64();
180 const MVT RegVT = Subtarget.getScalarIntVT();
188 if (!Subtarget.hasEFPU2())
205 if (!Subtarget.hasP10Vector()) {
231 if (Subtarget.isISA3_0()) {
264 if (!Subtarget.hasSPE()) {
271 if (Subtarget.useCRBits()) {
274 if (isPPC64 || Subtarget.hasFPCVT()) {
340 if (Subtarget.isISA3_0()) {
375 if (!Subtarget.hasSPE()) {
380 if (Subtarget.hasVSX()) {
385 if (Subtarget.hasFSQRT()) {
390 if (Subtarget.hasFPRND()) {
431 if (Subtarget.hasSPE()) {
441 if (Subtarget.hasSPE())
445 if (!Subtarget.hasFSQRT() &&
446 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
450 if (!Subtarget.hasFSQRT() &&
451 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
452 Subtarget.hasFRES()))
455 if (Subtarget.hasFCPSGN()) {
463 if (Subtarget.hasFPRND()) {
477 if (Subtarget.isISA3_1()) {
483 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
487 if (Subtarget.isISA3_0()) {
507 if (!Subtarget.useCRBits()) {
520 if (!Subtarget.useCRBits())
523 if (Subtarget.hasFPU()) {
534 if (!Subtarget.useCRBits())
539 if (Subtarget.hasSPE()) {
563 if (Subtarget.hasDirectMove() && isPPC64) {
568 if (TM.Options.UnsafeFPMath) {
620 if (Subtarget.is64BitELFABI()) {
631 }
else if (Subtarget.is32BitELFABI()) {
639 if (Subtarget.is32BitELFABI())
671 if (Subtarget.hasSPE()) {
693 if (Subtarget.has64BitSupport()) {
708 if (Subtarget.hasLFIWAX() || isPPC64) {
714 if (Subtarget.hasSPE()) {
724 if (Subtarget.hasFPCVT()) {
725 if (Subtarget.has64BitSupport()) {
746 if (Subtarget.use64BitRegs()) {
764 if (Subtarget.has64BitSupport()) {
771 if (Subtarget.hasVSX()) {
780 if (Subtarget.hasAltivec()) {
781 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
796 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
809 if (Subtarget.hasVSX()) {
815 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
825 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
899 if (!Subtarget.hasP8Vector()) {
941 if (Subtarget.hasAltivec())
942 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
945 if (Subtarget.hasP8Altivec())
956 if (Subtarget.hasVSX()) {
962 if (Subtarget.hasP8Altivec())
967 if (Subtarget.isISA3_1()) {
1013 if (Subtarget.hasVSX()) {
1016 if (Subtarget.hasP8Vector()) {
1020 if (Subtarget.hasDirectMove() && isPPC64) {
1034 if (TM.Options.UnsafeFPMath) {
1071 if (Subtarget.hasP8Vector())
1080 if (Subtarget.hasP8Altivec()) {
1107 if (Subtarget.isISA3_1())
1210 if (Subtarget.hasP8Altivec()) {
1215 if (Subtarget.hasP9Vector()) {
1220 if (Subtarget.useCRBits()) {
1280 }
else if (Subtarget.hasVSX()) {
1305 for (
MVT VT : {MVT::f32, MVT::f64}) {
1324 if (Subtarget.hasP9Altivec()) {
1325 if (Subtarget.isISA3_1()) {
1348 if (Subtarget.hasP10Vector()) {
1353 if (Subtarget.pairedVectorMemops()) {
1358 if (Subtarget.hasMMA()) {
1359 if (Subtarget.isISAFuture()) {
1375 if (Subtarget.has64BitSupport())
1378 if (Subtarget.isISA3_1())
1396 if (Subtarget.hasAltivec()) {
1413 if (Subtarget.hasFPCVT())
1416 if (Subtarget.useCRBits())
1425 if (Subtarget.useCRBits()) {
1431 if (Subtarget.useCRBits()) {
1444 auto CPUDirective = Subtarget.getCPUDirective();
1445 switch (CPUDirective) {
1468 if (Subtarget.enableMachineScheduler())
1542void PPCTargetLowering::initializeAddrModeMap() {
1593 if (MaxAlign == MaxMaxAlign)
1596 if (MaxMaxAlign >= 32 &&
1597 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1598 MaxAlign =
Align(32);
1599 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1601 MaxAlign =
Align(16);
1605 if (EltAlign > MaxAlign)
1606 MaxAlign = EltAlign;
1608 for (
auto *EltTy : STy->elements()) {
1611 if (EltAlign > MaxAlign)
1612 MaxAlign = EltAlign;
1613 if (MaxAlign == MaxMaxAlign)
1626 if (Subtarget.hasAltivec())
1632 return Subtarget.useSoftFloat();
1636 return Subtarget.hasSPE();
1644 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1645 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1649 if (VTy->getScalarType()->isIntegerTy()) {
1651 if (ElemSizeInBits == 32) {
1652 Index = Subtarget.isLittleEndian() ? 2 : 1;
1655 if (ElemSizeInBits == 64) {
1656 Index = Subtarget.isLittleEndian() ? 1 : 0;
1681 return "PPCISD::FTSQRT";
1683 return "PPCISD::FSQRT";
1688 return "PPCISD::XXSPLTI_SP_TO_DP";
1690 return "PPCISD::XXSPLTI32DX";
1694 return "PPCISD::XXPERM";
1697 return "PPCISD::VSRQ";
1716 return "PPCISD::CALL_RM";
1718 return "PPCISD::CALL_NOP_RM";
1720 return "PPCISD::CALL_NOTOC_RM";
1725 return "PPCISD::BCTRL_RM";
1727 return "PPCISD::BCTRL_LOAD_TOC_RM";
1739 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1741 return "PPCISD::ANDI_rec_1_EQ_BIT";
1743 return "PPCISD::ANDI_rec_1_GT_BIT";
1758 return "PPCISD::ST_VSR_SCAL_INT";
1787 return "PPCISD::PADDI_DTPREL";
1789 return "PPCISD::VADD_SPLAT";
1800 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1802 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1812 return "PPCISD::STRICT_FADDRTZ";
1814 return "PPCISD::STRICT_FCTIDZ";
1816 return "PPCISD::STRICT_FCTIWZ";
1818 return "PPCISD::STRICT_FCTIDUZ";
1820 return "PPCISD::STRICT_FCTIWUZ";
1822 return "PPCISD::STRICT_FCFID";
1824 return "PPCISD::STRICT_FCFIDU";
1826 return "PPCISD::STRICT_FCFIDS";
1828 return "PPCISD::STRICT_FCFIDUS";
1831 return "PPCISD::STORE_COND";
1833 return "PPCISD::SETBC";
1835 return "PPCISD::SETBCR";
1837 return "PPCISD::ADDC";
1839 return "PPCISD::ADDE";
1841 return "PPCISD::SUBC";
1843 return "PPCISD::SUBE";
1851 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1868 return CFP->getValueAPF().isZero();
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) {
2242 if (
N->getMaskElt(i) < 0) {
2243 for (
unsigned j = 1; j != EltSize; ++j)
2244 if (
N->getMaskElt(i + j) >= 0)
2247 for (
unsigned j = 0; j != EltSize; ++j)
2248 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2265 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2266 "Unexpected element width.");
2267 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2269 unsigned NumOfElem = 16 / Width;
2270 unsigned MaskVal[16];
2271 for (
unsigned i = 0; i < NumOfElem; ++i) {
2272 MaskVal[0] =
N->getMaskElt(i * Width);
2273 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2275 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2279 for (
unsigned int j = 1; j < Width; ++j) {
2280 MaskVal[j] =
N->getMaskElt(i * Width + j);
2281 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2291 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2296 unsigned M0 =
N->getMaskElt(0) / 4;
2297 unsigned M1 =
N->getMaskElt(4) / 4;
2298 unsigned M2 =
N->getMaskElt(8) / 4;
2299 unsigned M3 =
N->getMaskElt(12) / 4;
2300 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2301 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2306 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2307 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2308 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2309 InsertAtByte = IsLE ? 12 : 0;
2314 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2315 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2316 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2317 InsertAtByte = IsLE ? 8 : 4;
2322 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2323 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2324 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2325 InsertAtByte = IsLE ? 4 : 8;
2330 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2331 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2332 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2333 InsertAtByte = IsLE ? 0 : 12;
2340 if (
N->getOperand(1).isUndef()) {
2343 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2344 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2345 InsertAtByte = IsLE ? 12 : 0;
2348 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2349 InsertAtByte = IsLE ? 8 : 4;
2352 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2353 InsertAtByte = IsLE ? 4 : 8;
2356 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2357 InsertAtByte = IsLE ? 0 : 12;
2366 bool &Swap,
bool IsLE) {
2367 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2373 unsigned M0 =
N->getMaskElt(0) / 4;
2374 unsigned M1 =
N->getMaskElt(4) / 4;
2375 unsigned M2 =
N->getMaskElt(8) / 4;
2376 unsigned M3 =
N->getMaskElt(12) / 4;
2380 if (
N->getOperand(1).isUndef()) {
2381 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2382 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2385 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2391 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2395 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2400 ShiftElts = (8 -
M0) % 8;
2401 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2406 ShiftElts = (4 -
M0) % 4;
2411 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2416 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2428 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2433 for (
int i = 0; i < 16; i += Width)
2434 if (
N->getMaskElt(i) != i + Width - 1)
2465 bool &Swap,
bool IsLE) {
2466 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2472 unsigned M0 =
N->getMaskElt(0) / 8;
2473 unsigned M1 =
N->getMaskElt(8) / 8;
2474 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2478 if (
N->getOperand(1).isUndef()) {
2479 if ((
M0 |
M1) < 2) {
2480 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2488 if (
M0 > 1 &&
M1 < 2) {
2498 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2503 }
else if (
M0 > 1 &&
M1 < 2) {
2511 DM = (
M0 << 1) + (
M1 & 1);
2526 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2531 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2547 unsigned EltSize = 16/
N->getNumOperands();
2548 if (EltSize < ByteSize) {
2549 unsigned Multiple = ByteSize/EltSize;
2551 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2554 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2555 if (
N->getOperand(i).isUndef())
continue;
2559 if (!UniquedVals[i&(Multiple-1)].
getNode())
2560 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2561 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2571 bool LeadingZero =
true;
2572 bool LeadingOnes =
true;
2573 for (
unsigned i = 0; i != Multiple-1; ++i) {
2574 if (!UniquedVals[i].
getNode())
continue;
2581 if (!UniquedVals[Multiple-1].
getNode())
2588 if (!UniquedVals[Multiple-1].
getNode())
2599 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2600 if (
N->getOperand(i).isUndef())
continue;
2602 OpVal =
N->getOperand(i);
2603 else if (OpVal !=
N->getOperand(i))
2609 unsigned ValSizeInBytes = EltSize;
2612 Value = CN->getZExtValue();
2614 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2621 if (ValSizeInBytes < ByteSize)
return SDValue();
2632 if (MaskVal == 0)
return SDValue();
2652 Imm = (int16_t)
N->getAsZExtVal();
2653 if (
N->getValueType(0) == MVT::i32)
2654 return Imm == (int32_t)
N->getAsZExtVal();
2656 return Imm == (int64_t)
N->getAsZExtVal();
2674 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2682 for (
SDNode *U :
N->users()) {
2684 if (Memop->getMemoryVT() == MVT::f64) {
2685 Base =
N.getOperand(0);
2686 Index =
N.getOperand(1);
2729 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2734 Base =
N.getOperand(0);
2735 Index =
N.getOperand(1);
2737 }
else if (
N.getOpcode() ==
ISD::OR) {
2739 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2751 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2752 Base =
N.getOperand(0);
2753 Index =
N.getOperand(1);
2823 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2829 Base =
N.getOperand(0);
2832 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2834 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2835 "Cannot handle constant offsets yet!");
2836 Disp =
N.getOperand(1).getOperand(0);
2841 Base =
N.getOperand(0);
2844 }
else if (
N.getOpcode() ==
ISD::OR) {
2847 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2861 Base =
N.getOperand(0);
2874 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2877 CN->getValueType(0));
2882 if ((CN->getValueType(0) == MVT::i32 ||
2883 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2884 (!EncodingAlignment ||
2885 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2886 int Addr = (int)CN->getZExtValue();
2893 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2914 if (
N.getValueType() != MVT::i64)
2927 Base =
N.getOperand(0);
2943 Base =
N.getOperand(0);
2976 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2977 Base =
N.getOperand(0);
2978 Index =
N.getOperand(1);
3021 EVT MemVT = LD->getMemoryVT();
3028 if (!ST.hasP8Vector())
3033 if (!ST.hasP9Vector())
3045 if (
Use.getResNo() == 0 &&
3067 Ptr = LD->getBasePtr();
3068 VT = LD->getMemoryVT();
3069 Alignment = LD->getAlign();
3071 Ptr = ST->getBasePtr();
3072 VT = ST->getMemoryVT();
3073 Alignment = ST->getAlign();
3112 if (VT != MVT::i64) {
3117 if (Alignment <
Align(4))
3127 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3144 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3186 EVT VT = Subtarget.getScalarIntVT();
3188 : Subtarget.isAIXABI()
3200 EVT PtrVT =
Op.getValueType();
3206 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3207 if (Subtarget.isUsingPCRelativeCalls()) {
3216 return getTOCEntry(DAG, SDLoc(CP), GA);
3219 unsigned MOHiFlag, MOLoFlag;
3223 if (IsPIC && Subtarget.isSVR4ABI()) {
3226 return getTOCEntry(DAG, SDLoc(CP), GA);
3249 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3256 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3273 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3286 EVT PtrVT =
Op.getValueType();
3304 return getTOCEntry(DAG,
SDLoc(JT), GA);
3307 unsigned MOHiFlag, MOLoFlag;
3311 if (IsPIC && Subtarget.isSVR4ABI()) {
3314 return getTOCEntry(DAG, SDLoc(GA), GA);
3324 EVT PtrVT =
Op.getValueType();
3329 if (Subtarget.isUsingPCRelativeCalls()) {
3340 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3343 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3352 unsigned MOHiFlag, MOLoFlag;
3362 if (Subtarget.isAIXABI())
3363 return LowerGlobalTLSAddressAIX(
Op, DAG);
3365 return LowerGlobalTLSAddressLinux(
Op, DAG);
3387 if (
I.getOpcode() == Instruction::Call)
3389 if (
Function *CF = CI->getCalledFunction())
3390 if (CF->isDeclaration() &&
3391 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3399 unsigned TLSGVCnt = TLSGV.
size();
3409 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3422 const GlobalValue *GV = GA->
getGlobal();
3424 bool Is64Bit = Subtarget.isPPC64();
3428 if (Subtarget.hasAIXShLibTLSModelOpt())
3438 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3439 bool HasAIXSmallTLSGlobalAttr =
false;
3442 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3446 if (GVar->hasAttribute(
"aix-small-tls"))
3447 HasAIXSmallTLSGlobalAttr =
true;
3466 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3467 IsTLSLocalExecModel) {
3487 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3489 "currently only supported on AIX (64-bit mode).");
3495 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3499 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3501 "currently only supported on AIX (64-bit mode).");
3509 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3512 GlobalVariable *TLSGV =
3516 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3519 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3530 if (HasAIXSmallLocalDynamicTLS) {
3539 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3552 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3553 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3569 const GlobalValue *GV = GA->
getGlobal();
3571 bool is64bit = Subtarget.isPPC64();
3579 if (Subtarget.isUsingPCRelativeCalls()) {
3600 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3609 MachinePointerInfo());
3618 if (!TM.isPositionIndependent())
3631 if (Subtarget.isUsingPCRelativeCalls()) {
3655 if (Subtarget.isUsingPCRelativeCalls()) {
3677 PtrVT, GOTPtr, TGA, TGA);
3679 PtrVT, TLSAddr, TGA);
3688 EVT PtrVT =
Op.getValueType();
3691 const GlobalValue *GV = GSDN->
getGlobal();
3695 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3696 if (Subtarget.isUsingPCRelativeCalls()) {
3703 MachinePointerInfo());
3713 return getTOCEntry(DAG,
DL, GA);
3716 unsigned MOHiFlag, MOLoFlag;
3720 if (IsPIC && Subtarget.isSVR4ABI()) {
3724 return getTOCEntry(DAG,
DL, GA);
3736 bool IsStrict =
Op->isStrictFPOpcode();
3742 EVT LHSVT =
LHS.getValueType();
3746 if (LHSVT == MVT::f128) {
3747 assert(!Subtarget.hasP9Vector() &&
3748 "SETCC for f128 is already legal under Power9!");
3759 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3761 if (
Op.getValueType() == MVT::v2i64) {
3764 if (
LHS.getValueType() == MVT::v2i64) {
3770 dl, MVT::v4i32, DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
LHS),
3771 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
RHS), CC);
3772 int ShuffV[] = {1, 0, 3, 2};
3777 dl, MVT::v4i32, Shuff, SetCC32));
3794 if (
C->isAllOnes() ||
C->isZero())
3804 EVT VT =
Op.getValueType();
3812 SDNode *
Node =
Op.getNode();
3813 EVT VT =
Node->getValueType(0);
3820 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3824 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3827 if (VT == MVT::i64) {
3846 FprPtr, MachinePointerInfo(SV), MVT::i8);
3857 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3858 InChain = OverflowArea.
getValue(1);
3861 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3891 MachinePointerInfo(SV), MVT::i8);
3904 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3905 MachinePointerInfo(), MVT::i32);
3907 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3911 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3917 false,
true,
nullptr, std::nullopt,
3918 MachinePointerInfo(), MachinePointerInfo());
3923 return Op.getOperand(0);
3928 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3930 assert((
Op.getOpcode() == ISD::INLINEASM ||
3931 Op.getOpcode() == ISD::INLINEASM_BR) &&
3932 "Expecting Inline ASM node.");
3942 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3947 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3948 unsigned NumVals =
Flags.getNumOperandRegisters();
3951 switch (
Flags.getKind()) {
3962 for (; NumVals; --NumVals, ++i) {
3964 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
3987 if (Subtarget.isAIXABI()) {
3991 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
3992 MaybeAlign PointerAlign(PointerSize);
3993 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
3996 : MachineMemOperand::MONone;
4003 const Value *TrampolineAddr =
4013 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
4014 PointerAlign, MMOFlags);
4016 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
4017 MachinePointerInfo(TrampolineAddr, 0));
4021 SDValue TOCFromDescriptorPtr =
4023 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
4024 MachinePointerInfo(Func, TOCPointerOffset),
4025 PointerAlign, MMOFlags);
4026 SDValue TrampolineTOCPointer =
4030 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
4031 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
4037 DAG.
getStore(Chain, dl, Nest, EnvPointer,
4038 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
4045 bool isPPC64 = (PtrVT == MVT::i64);
4049 Args.emplace_back(Trmp, IntPtrTy);
4052 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
4054 Args.emplace_back(FPtr, IntPtrTy);
4055 Args.emplace_back(Nest, IntPtrTy);
4058 TargetLowering::CallLoweringInfo CLI(DAG);
4059 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4063 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4064 return CallResult.second;
4069 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4074 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
4079 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4080 MachinePointerInfo(SV));
4114 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4117 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4120 uint64_t FPROffset = 1;
4128 MachinePointerInfo(SV), MVT::i8);
4129 uint64_t nextOffset = FPROffset;
4136 MachinePointerInfo(SV, nextOffset), MVT::i8);
4137 nextOffset += StackOffset;
4138 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4141 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4142 MachinePointerInfo(SV, nextOffset));
4143 nextOffset += FrameOffset;
4144 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4147 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4148 MachinePointerInfo(SV, nextOffset));
4153static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4154 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4155 PPC::F11, PPC::F12, PPC::F13};
4160 unsigned PtrByteSize) {
4162 if (Flags.isByVal())
4163 ArgSize = Flags.getByValSize();
4167 if (!Flags.isInConsecutiveRegs())
4168 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4177 unsigned PtrByteSize) {
4178 Align Alignment(PtrByteSize);
4181 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4182 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4183 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4184 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4185 Alignment =
Align(16);
4188 if (Flags.isByVal()) {
4189 auto BVAlign = Flags.getNonZeroByValAlign();
4190 if (BVAlign > PtrByteSize) {
4191 if (BVAlign.value() % PtrByteSize != 0)
4193 "ByVal alignment is not a multiple of the pointer size");
4195 Alignment = BVAlign;
4200 if (Flags.isInConsecutiveRegs()) {
4204 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4218 unsigned PtrByteSize,
unsigned LinkageSize,
4219 unsigned ParamAreaSize,
unsigned &ArgOffset,
4220 unsigned &AvailableFPRs,
4221 unsigned &AvailableVRs) {
4222 bool UseMemory =
false;
4227 ArgOffset =
alignTo(ArgOffset, Alignment);
4230 if (ArgOffset >= LinkageSize + ParamAreaSize)
4235 if (Flags.isInConsecutiveRegsLast())
4236 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4239 if (ArgOffset > LinkageSize + ParamAreaSize)
4244 if (!Flags.isByVal()) {
4245 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4246 if (AvailableFPRs > 0) {
4250 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4251 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4252 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4253 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4254 if (AvailableVRs > 0) {
4266 unsigned NumBytes) {
4270SDValue PPCTargetLowering::LowerFormalArguments(
4274 if (Subtarget.isAIXABI())
4275 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4277 if (Subtarget.is64BitELFABI())
4278 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4280 assert(Subtarget.is32BitELFABI());
4281 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4285SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4321 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4327 const Align PtrAlign(4);
4335 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4336 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4339 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4340 CCValAssign &VA = ArgLocs[i];
4344 const TargetRegisterClass *RC;
4352 RC = &PPC::GPRCRegClass;
4355 if (Subtarget.hasP8Vector())
4356 RC = &PPC::VSSRCRegClass;
4357 else if (Subtarget.hasSPE())
4358 RC = &PPC::GPRCRegClass;
4360 RC = &PPC::F4RCRegClass;
4363 if (Subtarget.hasVSX())
4364 RC = &PPC::VSFRCRegClass;
4365 else if (Subtarget.hasSPE())
4367 RC = &PPC::GPRCRegClass;
4369 RC = &PPC::F8RCRegClass;
4374 RC = &PPC::VRRCRegClass;
4377 RC = &PPC::VRRCRegClass;
4381 RC = &PPC::VRRCRegClass;
4388 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4389 assert(i + 1 < e &&
"No second half of double precision argument");
4394 if (!Subtarget.isLittleEndian())
4401 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4402 if (ValVT == MVT::i1)
4417 ArgOffset += ArgSize - ObjSize;
4435 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4440 unsigned MinReservedArea = CCByValInfo.getStackSize();
4441 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4457 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4458 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4460 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4463 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4466 unsigned NumFPArgRegs = std::size(FPArgRegs);
4475 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4476 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4479 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4492 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4507 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4511 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4524 if (!MemOps.
empty())
4535 const SDLoc &dl)
const {
4539 else if (
Flags.isZExt())
4546SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4552 bool isELFv2ABI = Subtarget.isELFv2ABI();
4553 bool isLittleEndian = Subtarget.isLittleEndian();
4556 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4559 "fastcc not supported on varargs functions");
4565 unsigned PtrByteSize = 8;
4566 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4569 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4570 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4573 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4574 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4577 const unsigned Num_GPR_Regs = std::size(GPR);
4579 const unsigned Num_VR_Regs = std::size(VR);
4587 bool HasParameterArea = !isELFv2ABI || isVarArg;
4588 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4589 unsigned NumBytes = LinkageSize;
4590 unsigned AvailableFPRs = Num_FPR_Regs;
4591 unsigned AvailableVRs = Num_VR_Regs;
4592 for (
const ISD::InputArg &In : Ins) {
4593 if (
In.Flags.isNest())
4597 LinkageSize, ParamAreaSize, NumBytes,
4598 AvailableFPRs, AvailableVRs))
4599 HasParameterArea =
true;
4606 unsigned ArgOffset = LinkageSize;
4607 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4610 unsigned CurArgIdx = 0;
4611 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4613 bool needsLoad =
false;
4614 EVT ObjectVT =
Ins[ArgNo].VT;
4615 EVT OrigVT =
Ins[ArgNo].ArgVT;
4617 unsigned ArgSize = ObjSize;
4618 ISD::ArgFlagsTy
Flags =
Ins[ArgNo].Flags;
4619 if (Ins[ArgNo].isOrigArg()) {
4620 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4621 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4626 unsigned CurArgOffset;
4628 auto ComputeArgOffset = [&]() {
4632 ArgOffset =
alignTo(ArgOffset, Alignment);
4633 CurArgOffset = ArgOffset;
4640 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4641 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4646 if (
Flags.isByVal()) {
4647 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4653 ObjSize =
Flags.getByValSize();
4654 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4676 if (HasParameterArea ||
4677 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4684 if (ObjSize < PtrByteSize) {
4688 if (!isLittleEndian) {
4694 if (GPR_idx != Num_GPR_Regs) {
4701 MachinePointerInfo(&*FuncArg), ObjType);
4706 ArgOffset += PtrByteSize;
4715 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4716 if (GPR_idx == Num_GPR_Regs)
4727 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4731 MachinePointerInfo(&*FuncArg, j), ObjType);
4735 ArgOffset += ArgSize;
4744 if (
Flags.isNest()) {
4749 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4750 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4758 if (GPR_idx != Num_GPR_Regs) {
4763 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4766 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4772 ArgSize = PtrByteSize;
4783 if (FPR_idx != Num_FPR_Regs) {
4786 if (ObjectVT == MVT::f32)
4788 Subtarget.hasP8Vector()
4789 ? &PPC::VSSRCRegClass
4790 : &PPC::F4RCRegClass);
4793 ? &PPC::VSFRCRegClass
4794 : &PPC::F8RCRegClass);
4809 if (ObjectVT == MVT::f32) {
4810 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4816 ArgVal = DAG.
getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
4828 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4829 ArgOffset += ArgSize;
4830 if (
Flags.isInConsecutiveRegsLast())
4831 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4845 if (VR_idx != Num_VR_Regs) {
4862 if (ObjSize < ArgSize && !isLittleEndian)
4863 CurArgOffset += ArgSize - ObjSize;
4866 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4873 unsigned MinReservedArea;
4874 if (HasParameterArea)
4875 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4877 MinReservedArea = LinkageSize;
4894 int Depth = ArgOffset;
4903 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4904 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4916 if (!MemOps.
empty())
4925 unsigned ParamSize) {
4927 if (!isTailCall)
return 0;
4931 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4933 if (SPDiff < FI->getTailCallSPDelta())
4949 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4962 if (!TM.shouldAssumeDSOLocal(CalleeGV))
5007 if (TM.getFunctionSections() || CalleeGV->
hasComdat() ||
5008 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
5011 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
5023 const unsigned PtrByteSize = 8;
5027 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
5028 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
5031 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
5032 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
5035 const unsigned NumGPRs = std::size(GPR);
5036 const unsigned NumFPRs = 13;
5037 const unsigned NumVRs = std::size(VR);
5038 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5040 unsigned NumBytes = LinkageSize;
5041 unsigned AvailableFPRs = NumFPRs;
5042 unsigned AvailableVRs = NumVRs;
5045 if (Param.Flags.isNest())
continue;
5048 LinkageSize, ParamAreaSize, NumBytes,
5049 AvailableFPRs, AvailableVRs))
5060 auto CalleeArgEnd = CB.
arg_end();
5063 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5064 const Value* CalleeArg = *CalleeArgIter;
5065 const Value* CallerArg = &(*CallerArgIter);
5066 if (CalleeArg == CallerArg)
5092 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5102bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5107 bool isCalleeExternalSymbol)
const {
5110 if (
DisableSCO && !TailCallOpt)
return false;
5113 if (isVarArg)
return false;
5120 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5156 if (!Subtarget.isUsingPCRelativeCalls() &&
5161 if (!Subtarget.isUsingPCRelativeCalls() &&
5189bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5202 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5223 if (!
C)
return nullptr;
5225 int Addr =
C->getZExtValue();
5226 if ((Addr & 3) != 0 ||
5232 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5239struct TailCallArgumentInfo {
5244 TailCallArgumentInfo() =
default;
5254 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5255 SDValue Arg = TailCallArgs[i].Arg;
5256 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5257 int FI = TailCallArgs[i].FrameIdx;
5260 Chain, dl, Arg, FIN,
5269 int SPDiff,
const SDLoc &dl) {
5275 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5276 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5278 NewRetAddrLoc,
true);
5281 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5291 int SPDiff,
unsigned ArgOffset,
5293 int Offset = ArgOffset + SPDiff;
5296 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5298 TailCallArgumentInfo
Info;
5300 Info.FrameIdxOp = FIN;
5308SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5313 LROpOut = getReturnAddrFrameIndex(DAG);
5314 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5315 MachinePointerInfo());
5332 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5340 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5364 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5374 if (!MemOpChains2.
empty())
5398SDValue PPCTargetLowering::LowerCallResult(
5406 CCRetInfo.AnalyzeCallResult(
5412 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5413 CCValAssign &VA = RVLocs[i];
5418 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5428 if (!Subtarget.isLittleEndian())
5496 bool IsStrictFPCall =
false) {
5500 unsigned RetOpc = 0;
5531 if (IsStrictFPCall) {
5562 auto isLocalCallee = [&]() {
5578 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5595 return getAIXFuncEntryPointSymbolSDNode(GV);
5602 const char *SymName = S->getSymbol();
5609 return getAIXFuncEntryPointSymbolSDNode(
F);
5615 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5623 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5630 assert(Callee.getNode() &&
"What no callee?");
5636 "Expected a CALLSEQ_STARTSDNode.");
5653 SDValue MTCTROps[] = {Chain, Callee, Glue};
5654 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5695 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5714 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5715 Alignment, MMOFlags);
5722 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5729 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5741 "Nest parameter is not supported on AIX.");
5757 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5760 const bool IsPPC64 = Subtarget.isPPC64();
5765 Ops.push_back(Chain);
5769 Ops.push_back(Callee);
5789 Ops.push_back(AddTOC);
5800 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5809 for (
const auto &[
Reg,
N] : RegsToPass)
5827 assert(Mask &&
"Missing call preserved mask for calling convention");
5832 Ops.push_back(Glue);
5835SDValue PPCTargetLowering::FinishCall(
5842 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5843 Subtarget.isAIXABI())
5850 if (!CFlags.IsIndirect)
5852 else if (Subtarget.usesFunctionDescriptors())
5854 dl, CFlags.HasNest, Subtarget);
5864 if (CFlags.IsTailCall) {
5872 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5873 "Expecting a global address, external symbol, absolute value, "
5874 "register or an indirect tail call when PC Relative calls are "
5878 "Unexpected call opcode for a tail call.");
5885 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5886 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5898 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5901 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5921 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5922 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5926bool PPCTargetLowering::isEligibleForTCO(
5931 bool isCalleeExternalSymbol)
const {
5935 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5936 return IsEligibleForTailCallOptimization_64SVR4(
5937 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5938 isCalleeExternalSymbol);
5940 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5968 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5983 "Callee should be an llvm::Function object.");
5986 <<
"\nTCO callee: ");
5993 "site marked musttail");
6000 Callee = LowerGlobalAddress(Callee, DAG);
6003 CallConv, isTailCall, isVarArg, isPatchPoint,
6006 Subtarget.is64BitELFABI() &&
6010 if (Subtarget.isAIXABI())
6011 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6014 assert(Subtarget.isSVR4ABI());
6015 if (Subtarget.isPPC64())
6016 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6018 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6022SDValue PPCTargetLowering::LowerCall_32SVR4(
6033 const bool IsVarArg = CFlags.IsVarArg;
6034 const bool IsTailCall = CFlags.IsTailCall;
6040 const Align PtrAlign(4);
6051 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6059 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6062 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6069 unsigned NumArgs = Outs.
size();
6071 for (
unsigned i = 0; i != NumArgs; ++i) {
6072 MVT ArgVT = Outs[i].VT;
6073 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6078 Outs[i].OrigTy, CCInfo);
6081 ArgFlags, Outs[i].OrigTy, CCInfo);
6086 errs() <<
"Call operand #" << i <<
" has unhandled type "
6099 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6102 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6109 unsigned NumBytes = CCByValInfo.getStackSize();
6123 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6134 bool seenFloatArg =
false;
6139 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6141 ++i, ++RealArgIdx) {
6142 CCValAssign &VA = ArgLocs[i];
6143 SDValue Arg = OutVals[RealArgIdx];
6144 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6146 if (
Flags.isByVal()) {
6151 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6152 CCValAssign &ByValVA = ByValArgLocs[
j++];
6174 Chain = CallSeqStart = NewCallSeqStart;
6193 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6194 bool IsLE = Subtarget.isLittleEndian();
6200 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6215 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6224 if (!MemOpChains.
empty())
6230 for (
const auto &[
Reg,
N] : RegsToPass) {
6238 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6251 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6252 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6257SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6269 return NewCallSeqStart;
6272SDValue PPCTargetLowering::LowerCall_64SVR4(
6279 bool isELFv2ABI = Subtarget.isELFv2ABI();
6280 bool isLittleEndian = Subtarget.isLittleEndian();
6282 bool IsSibCall =
false;
6286 unsigned PtrByteSize = 8;
6299 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6301 assert(!(IsFastCall && CFlags.IsVarArg) &&
6302 "fastcc not supported on varargs functions");
6308 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6309 unsigned NumBytes = LinkageSize;
6310 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6313 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6314 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6317 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6318 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6321 const unsigned NumGPRs = std::size(GPR);
6323 const unsigned NumVRs = std::size(VR);
6329 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6330 if (!HasParameterArea) {
6331 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6332 unsigned AvailableFPRs = NumFPRs;
6333 unsigned AvailableVRs = NumVRs;
6334 unsigned NumBytesTmp = NumBytes;
6335 for (
unsigned i = 0; i !=
NumOps; ++i) {
6336 if (Outs[i].
Flags.isNest())
continue;
6338 PtrByteSize, LinkageSize, ParamAreaSize,
6339 NumBytesTmp, AvailableFPRs, AvailableVRs))
6340 HasParameterArea =
true;
6346 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6351 HasParameterArea =
false;
6354 for (
unsigned i = 0; i !=
NumOps; ++i) {
6355 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6356 EVT ArgVT = Outs[i].VT;
6357 EVT OrigVT = Outs[i].ArgVT;
6363 if (
Flags.isByVal()) {
6364 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6365 if (NumGPRsUsed > NumGPRs)
6366 HasParameterArea =
true;
6373 if (++NumGPRsUsed <= NumGPRs)
6383 if (++NumVRsUsed <= NumVRs)
6387 if (++NumVRsUsed <= NumVRs)
6392 if (++NumFPRsUsed <= NumFPRs)
6396 HasParameterArea =
true;
6403 NumBytes =
alignTo(NumBytes, Alignement);
6406 if (
Flags.isInConsecutiveRegsLast())
6407 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6410 unsigned NumBytesActuallyUsed = NumBytes;
6420 if (HasParameterArea)
6421 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6423 NumBytes = LinkageSize;
6438 if (CFlags.IsTailCall)
6450 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6461 unsigned ArgOffset = LinkageSize;
6467 for (
unsigned i = 0; i !=
NumOps; ++i) {
6469 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6470 EVT ArgVT = Outs[i].VT;
6471 EVT OrigVT = Outs[i].ArgVT;
6480 auto ComputePtrOff = [&]() {
6484 ArgOffset =
alignTo(ArgOffset, Alignment);
6495 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6496 GPR_idx = std::min(GPR_idx, NumGPRs);
6503 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6509 if (
Flags.isByVal()) {
6527 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6528 if (GPR_idx != NumGPRs) {
6530 MachinePointerInfo(), VT);
6532 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6534 ArgOffset += PtrByteSize;
6539 if (GPR_idx == NumGPRs &&
Size < 8) {
6541 if (!isLittleEndian) {
6546 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6549 ArgOffset += PtrByteSize;
6558 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6559 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6564 if (
Size < 8 && GPR_idx != NumGPRs) {
6574 if (!isLittleEndian) {
6578 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6584 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6586 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6589 ArgOffset += PtrByteSize;
6595 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6598 if (GPR_idx != NumGPRs) {
6599 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6602 MachinePointerInfo(), ObjType);
6605 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6606 ArgOffset += PtrByteSize;
6608 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6620 if (
Flags.isNest()) {
6622 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6629 if (GPR_idx != NumGPRs) {
6630 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6635 assert(HasParameterArea &&
6636 "Parameter area must exist to pass an argument in memory.");
6638 true, CFlags.IsTailCall,
false, MemOpChains,
6639 TailCallArguments, dl);
6641 ArgOffset += PtrByteSize;
6644 ArgOffset += PtrByteSize;
6657 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6658 bool NeededLoad =
false;
6661 if (FPR_idx != NumFPRs)
6662 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6665 if (!NeedGPROrStack)
6667 else if (GPR_idx != NumGPRs && !IsFastCall) {
6678 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i64, Arg);
6681 }
else if (!
Flags.isInConsecutiveRegs()) {
6682 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6687 }
else if (ArgOffset % PtrByteSize != 0) {
6689 Lo = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, OutVals[i - 1]);
6690 Hi = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6691 if (!isLittleEndian)
6696 }
else if (
Flags.isInConsecutiveRegsLast()) {
6697 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6699 if (!isLittleEndian)
6709 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6717 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6722 assert(HasParameterArea &&
6723 "Parameter area must exist to pass an argument in memory.");
6725 true, CFlags.IsTailCall,
false, MemOpChains,
6726 TailCallArguments, dl);
6733 if (!IsFastCall || NeededLoad) {
6735 Flags.isInConsecutiveRegs()) ? 4 : 8;
6736 if (
Flags.isInConsecutiveRegsLast())
6737 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6757 if (CFlags.IsVarArg) {
6758 assert(HasParameterArea &&
6759 "Parameter area must exist if we have a varargs call.");
6763 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6765 if (VR_idx != NumVRs) {
6767 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6769 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6772 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6773 if (GPR_idx == NumGPRs)
6778 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6780 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6786 if (VR_idx != NumVRs) {
6787 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6792 assert(HasParameterArea &&
6793 "Parameter area must exist to pass an argument in memory.");
6795 true, CFlags.IsTailCall,
true, MemOpChains,
6796 TailCallArguments, dl);
6807 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6808 "mismatch in size of parameter area");
6809 (void)NumBytesActuallyUsed;
6811 if (!MemOpChains.
empty())
6817 if (CFlags.IsIndirect) {
6821 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6826 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6836 if (isELFv2ABI && !CFlags.IsPatchPoint)
6837 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6843 for (
const auto &[
Reg,
N] : RegsToPass) {
6848 if (CFlags.IsTailCall && !IsSibCall)
6852 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6853 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6860 "Required alignment greater than stack alignment.");
6880 return RequiredAlign <= 8;
6885 return RequiredAlign <= 4;
6893 State.getMachineFunction().getSubtarget());
6894 const bool IsPPC64 = Subtarget.isPPC64();
6895 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6896 const Align PtrAlign(PtrSize);
6897 const Align StackAlign(16);
6900 if (ValVT == MVT::f128)
6904 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6905 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6907 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6908 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6911 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6912 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6913 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6918 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6927 if (ByValAlign > StackAlign)
6929 "16 are not supported.");
6932 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6936 if (ByValSize == 0) {
6938 State.getStackSize(), RegVT, LocInfo));
6943 unsigned NextReg = State.getFirstUnallocated(GPRs);
6944 while (NextReg != GPRs.
size() &&
6949 State.AllocateStack(PtrSize, PtrAlign);
6950 assert(
Reg &&
"Alocating register unexpectedly failed.");
6952 NextReg = State.getFirstUnallocated(GPRs);
6955 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6956 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6976 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6980 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
6999 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
7005 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
7007 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
7008 if (State.isVarArg()) {
7040 const unsigned VecSize = 16;
7041 const Align VecAlign(VecSize);
7043 if (!State.isVarArg()) {
7046 if (
MCRegister VReg = State.AllocateReg(VR)) {
7053 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7058 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7061 while (NextRegIndex != GPRs.
size() &&
7065 State.AllocateStack(PtrSize, PtrAlign);
7066 assert(
Reg &&
"Allocating register unexpectedly failed.");
7068 NextRegIndex = State.getFirstUnallocated(GPRs);
7076 if (
MCRegister VReg = State.AllocateReg(VR)) {
7079 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7080 State.AllocateReg(GPRs);
7081 State.AllocateStack(VecSize, VecAlign);
7085 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7091 if (NextRegIndex == GPRs.
size()) {
7092 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7100 if (GPRs[NextRegIndex] == PPC::R9) {
7101 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7105 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7106 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7107 assert(FirstReg && SecondReg &&
7108 "Allocating R9 or R10 unexpectedly failed.");
7119 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7122 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7124 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7139 assert((IsPPC64 || SVT != MVT::i64) &&
7140 "i64 should have been split for 32-bit codegen.");
7148 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7150 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7152 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7160 return &PPC::VRRCRegClass;
7173 else if (Flags.isZExt())
7185 "Reg must be a valid argument register!");
7186 return LASize + 4 * (
Reg - PPC::R3);
7191 "Reg must be a valid argument register!");
7192 return LASize + 8 * (
Reg - PPC::X3);
7238SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7245 "Unexpected calling convention!");
7253 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7255 const bool IsPPC64 = Subtarget.isPPC64();
7256 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7262 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7263 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7267 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7268 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7269 uint64_t SaveStackPos = CCInfo.getStackSize();
7271 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7275 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7276 CCValAssign &VA = ArgLocs[
I++];
7282 bool ArgSignExt =
Ins[VA.
getValNo()].Flags.isSExt();
7294 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7296 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7302 MachinePointerInfo(),
Align(PtrByteSize));
7308 unsigned StoreSize =
7310 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7313 auto HandleMemLoc = [&]() {
7316 assert((ValSize <= LocSize) &&
7317 "Object size is larger than size of MemLoc");
7320 if (LocSize > ValSize)
7321 CurArgOffset += LocSize - ValSize;
7323 const bool IsImmutable =
7329 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7363 assert(isVarArg &&
"Only use custom memloc for vararg.");
7366 const unsigned OriginalValNo = VA.
getValNo();
7367 (void)OriginalValNo;
7369 auto HandleCustomVecRegLoc = [&]() {
7370 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7371 "Missing custom RegLoc.");
7374 "Unexpected Val type for custom RegLoc.");
7376 "ValNo mismatch between custom MemLoc and RegLoc.");
7380 Subtarget.hasVSX()));
7387 HandleCustomVecRegLoc();
7388 HandleCustomVecRegLoc();
7392 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7394 "Only 2 custom RegLocs expected for 64-bit codegen.");
7395 HandleCustomVecRegLoc();
7396 HandleCustomVecRegLoc();
7440 const unsigned Size =
7452 if (
Flags.isByVal()) {
7456 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7458 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7466 const TargetRegisterClass *RegClass =
7467 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7469 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7482 CopyFrom.
getValue(1), dl, CopyFrom,
7492 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7495 "RegLocs should be for ByVal argument.");
7497 const CCValAssign RL = ArgLocs[
I++];
7502 if (
Offset != StackSize) {
7504 "Expected MemLoc for remaining bytes.");
7505 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7519 Subtarget.hasVSX()));
7536 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7538 unsigned CallerReservedArea = std::max<unsigned>(
7539 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7545 CallerReservedArea =
7554 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7555 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7557 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7558 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7559 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7564 for (
unsigned GPRIndex =
7565 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7566 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7569 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7570 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7582 if (!MemOps.
empty())
7588SDValue PPCTargetLowering::LowerCall_AIX(
7601 "Unexpected calling convention!");
7603 if (CFlags.IsPatchPoint)
7606 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7610 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7617 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7618 const bool IsPPC64 = Subtarget.isPPC64();
7620 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7621 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7622 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7630 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7631 const unsigned NumBytes = std::max<unsigned>(
7632 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7648 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7649 const unsigned ValNo = ArgLocs[
I].getValNo();
7651 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7653 if (
Flags.isByVal()) {
7654 const unsigned ByValSize =
Flags.getByValSize();
7662 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7668 MachinePointerInfo(), VT);
7671 unsigned LoadOffset = 0;
7674 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7677 LoadOffset += PtrByteSize;
7678 const CCValAssign &ByValVA = ArgLocs[
I++];
7680 "Unexpected location for pass-by-value argument.");
7684 if (LoadOffset == ByValSize)
7688 assert(ArgLocs[
I].getValNo() == ValNo &&
7689 "Expected additional location for by-value argument.");
7691 if (ArgLocs[
I].isMemLoc()) {
7692 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7693 const CCValAssign &ByValVA = ArgLocs[
I++];
7694 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7697 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7703 CallSeqStart, MemcpyFlags, DAG, dl);
7712 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7713 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7714 "Unexpected register residue for by-value argument.");
7716 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7720 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7730 "Unexpected load emitted during handling of pass-by-value "
7738 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7743 const CCValAssign &ByValVA = ArgLocs[
I++];
7748 CCValAssign &VA = ArgLocs[
I++];
7773 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7779 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7781 const unsigned OriginalValNo = VA.
getValNo();
7783 unsigned LoadOffset = 0;
7784 auto HandleCustomVecRegLoc = [&]() {
7785 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7786 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7787 "Expected custom RegLoc.");
7788 CCValAssign RegVA = ArgLocs[
I++];
7790 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7796 LoadOffset += PtrByteSize;
7802 HandleCustomVecRegLoc();
7803 HandleCustomVecRegLoc();
7805 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7806 ArgLocs[
I].getValNo() == OriginalValNo) {
7808 "Only 2 custom RegLocs expected for 64-bit codegen.");
7809 HandleCustomVecRegLoc();
7810 HandleCustomVecRegLoc();
7821 DAG.
getStore(Chain, dl, Arg, PtrOff,
7823 Subtarget.getFrameLowering()->getStackAlign()));
7830 "Unexpected register handling for calling convention.");
7836 "Custom register handling only expected for VarArg.");
7841 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7845 else if (Arg.getValueType().getFixedSizeInBits() <
7853 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7854 "Unexpected custom register for argument!");
7855 CCValAssign &GPR1 = VA;
7864 CCValAssign &PeekArg = ArgLocs[
I];
7867 CCValAssign &GPR2 = ArgLocs[
I++];
7875 if (!MemOpChains.
empty())
7880 if (CFlags.IsIndirect) {
7881 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7882 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7883 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7884 const MVT PtrVT = Subtarget.getScalarIntVT();
7885 const unsigned TOCSaveOffset =
7886 Subtarget.getFrameLowering()->getTOCSaveOffset();
7901 for (
auto Reg : RegsToPass) {
7906 const int SPDiff = 0;
7907 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7908 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7916 const Type *RetTy)
const {
7918 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7919 return CCInfo.CheckReturn(
7934 CCInfo.AnalyzeReturn(Outs,
7943 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7944 CCValAssign &VA = RVLocs[i];
7947 SDValue Arg = OutVals[RealResIdx];
7962 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7963 bool isLittleEndian = Subtarget.isLittleEndian();
7985 RetOps.push_back(Glue);
7991PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7996 EVT IntVT =
Op.getValueType();
8000 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8016 bool isPPC64 = Subtarget.isPPC64();
8017 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
8026 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
8032 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8037 bool isPPC64 = Subtarget.isPPC64();
8042 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8048 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8058PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8060 bool isPPC64 = Subtarget.isPPC64();
8065 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8071 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8094 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8096 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8106 bool isPPC64 = Subtarget.isPPC64();
8118 Op.getOperand(0),
Op.getOperand(1));
8125 Op.getOperand(0),
Op.getOperand(1));
8129 if (
Op.getValueType().isVector())
8130 return LowerVectorLoad(
Op, DAG);
8132 assert(
Op.getValueType() == MVT::i1 &&
8133 "Custom lowering only for i1 loads");
8142 MachineMemOperand *MMO =
LD->getMemOperand();
8146 BasePtr, MVT::i8, MMO);
8154 if (
Op.getOperand(1).getValueType().isVector())
8155 return LowerVectorStore(
Op, DAG);
8157 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8158 "Custom lowering only for i1 stores");
8168 MachineMemOperand *MMO =
ST->getMemOperand();
8177 assert(
Op.getValueType() == MVT::i1 &&
8178 "Custom lowering only for i1 results");
8206 EVT TrgVT =
Op.getValueType();
8230 if (SrcSize == 256) {
8241 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8247 SmallVector<int, 16> ShuffV;
8248 if (Subtarget.isLittleEndian())
8249 for (
unsigned i = 0; i < TrgNumElts; ++i)
8252 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8256 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8260 Op1 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op1);
8261 Op2 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op2);
8269 EVT ResVT =
Op.getValueType();
8270 EVT CmpVT =
Op.getOperand(0).getValueType();
8272 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8278 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8291 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8295 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8327 if (
LHS.getValueType() == MVT::f32)
8331 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8333 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), Sel1, FV);
8340 if (
LHS.getValueType() == MVT::f32)
8349 if (
LHS.getValueType() == MVT::f32)
8352 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), TV, FV);
8363 if (
Cmp.getValueType() == MVT::f32)
8364 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8367 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8369 DAG.
getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
8373 if (
Cmp.getValueType() == MVT::f32)
8374 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8379 if (
Cmp.getValueType() == MVT::f32)
8380 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8385 if (
Cmp.getValueType() == MVT::f32)
8386 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8391 if (
Cmp.getValueType() == MVT::f32)
8392 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8424 bool IsStrict =
Op->isStrictFPOpcode();
8433 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8435 MVT DestTy =
Op.getSimpleValueType();
8436 assert(Src.getValueType().isFloatingPoint() &&
8437 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8438 DestTy == MVT::i64) &&
8439 "Invalid FP_TO_INT types");
8440 if (Src.getValueType() == MVT::f32) {
8444 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8447 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
8449 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8459 assert((IsSigned || Subtarget.hasFPCVT()) &&
8460 "i64 FP_TO_UINT is supported only with FPCVT");
8463 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8475void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8477 const SDLoc &dl)
const {
8481 bool IsStrict =
Op->isStrictFPOpcode();
8484 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8485 (IsSigned || Subtarget.hasFPCVT());
8488 MachinePointerInfo MPI =
8496 Alignment =
Align(4);
8497 MachineMemOperand *MMO =
8503 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8507 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8508 !Subtarget.isLittleEndian()) {
8517 RLI.Alignment = Alignment;
8525 const SDLoc &dl)
const {
8528 if (
Op->isStrictFPOpcode())
8535 const SDLoc &dl)
const {
8536 bool IsStrict =
Op->isStrictFPOpcode();
8539 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8540 EVT SrcVT = Src.getValueType();
8541 EVT DstVT =
Op.getValueType();
8544 if (SrcVT == MVT::f128)
8545 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8549 if (SrcVT == MVT::ppcf128) {
8550 if (DstVT == MVT::i32) {
8555 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8566 {Op.getOperand(0), Lo, Hi}, Flags);
8569 {Res.getValue(1), Res}, Flags);
8575 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8599 {Chain, Src, FltOfs}, Flags);
8603 {Chain, Val}, Flags);
8606 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8624 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8625 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8628 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8630 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8631 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8642bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8647 if (
Op->isStrictFPOpcode())
8652 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8656 Op.getOperand(0).getValueType())) {
8658 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8663 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8664 LD->isNonTemporal())
8666 if (
LD->getMemoryVT() != MemVT)
8676 RLI.Ptr =
LD->getBasePtr();
8677 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8679 "Non-pre-inc AM on PPC?");
8684 RLI.Chain =
LD->getChain();
8685 RLI.MPI =
LD->getPointerInfo();
8686 RLI.IsDereferenceable =
LD->isDereferenceable();
8687 RLI.IsInvariant =
LD->isInvariant();
8688 RLI.Alignment =
LD->getAlign();
8689 RLI.AAInfo =
LD->getAAInfo();
8690 RLI.Ranges =
LD->getRanges();
8692 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8699bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8700 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8707 if (!Subtarget.hasP9Vector() &&
8711 for (SDUse &Use : Origin->
uses()) {
8714 if (
Use.getResNo() != 0)
8741 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8744 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8745 if (
Op->isStrictFPOpcode()) {
8747 Chain =
Op.getOperand(0);
8749 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8751 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8759 const SDLoc &dl)
const {
8760 assert((
Op.getValueType() == MVT::f32 ||
8761 Op.getValueType() == MVT::f64) &&
8762 "Invalid floating point type as target of conversion");
8763 assert(Subtarget.hasFPCVT() &&
8764 "Int to FP conversions with direct moves require FPCVT");
8765 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8766 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8788 for (
unsigned i = 1; i < NumConcat; ++i)
8795 const SDLoc &dl)
const {
8796 bool IsStrict =
Op->isStrictFPOpcode();
8797 unsigned Opc =
Op.getOpcode();
8798 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8801 "Unexpected conversion type");
8802 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8803 "Supports conversions to v2f64/v4f32 only.");
8807 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8810 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8815 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8817 SmallVector<int, 16> ShuffV;
8818 for (
unsigned i = 0; i < WideNumElts; ++i)
8821 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8822 int SaveElts = FourEltRes ? 4 : 2;
8823 if (Subtarget.isLittleEndian())
8824 for (
int i = 0; i < SaveElts; i++)
8825 ShuffV[i * Stride] = i;
8827 for (
int i = 1; i <= SaveElts; i++)
8828 ShuffV[i * Stride - 1] = i - 1;
8836 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8837 EVT ExtVT = Src.getValueType();
8838 if (Subtarget.hasP9Altivec())
8845 Extend = DAG.
getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
8849 {Op.getOperand(0), Extend}, Flags);
8851 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8859 bool IsStrict =
Op->isStrictFPOpcode();
8860 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8865 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8867 EVT InVT = Src.getValueType();
8868 EVT OutVT =
Op.getValueType();
8871 return LowerINT_TO_FPVector(
Op, DAG, dl);
8874 if (
Op.getValueType() == MVT::f128)
8875 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8878 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8881 if (Src.getValueType() == MVT::i1) {
8893 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8894 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8895 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8897 assert((IsSigned || Subtarget.hasFPCVT()) &&
8898 "UINT_TO_FP is supported only with FPCVT");
8900 if (Src.getValueType() == MVT::i64) {
8912 if (
Op.getValueType() == MVT::f32 &&
8913 !Subtarget.hasFPCVT() &&
8954 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8955 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8956 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8959 }
else if (Subtarget.hasLFIWAX() &&
8960 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8961 MachineMemOperand *MMO =
8963 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8967 Ops, MVT::i32, MMO);
8970 }
else if (Subtarget.hasFPCVT() &&
8971 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8972 MachineMemOperand *MMO =
8974 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8978 Ops, MVT::i32, MMO);
8981 }
else if (((Subtarget.hasLFIWAX() &&
8983 (Subtarget.hasFPCVT() &&
8998 "Expected an i32 store");
9004 RLI.Alignment =
Align(4);
9006 MachineMemOperand *MMO =
9008 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9012 dl, DAG.
getVTList(MVT::f64, MVT::Other),
9013 Ops, MVT::i32, MMO);
9014 Chain =
Bits.getValue(1);
9016 Bits = DAG.
getNode(ISD::BITCAST, dl, MVT::f64, SINT);
9022 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9026 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9035 assert(Src.getValueType() == MVT::i32 &&
9036 "Unhandled INT_TO_FP type in custom expander!");
9046 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9049 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9059 "Expected an i32 store");
9065 RLI.Alignment =
Align(4);
9068 MachineMemOperand *MMO =
9070 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9076 if (ReusingLoad && RLI.ResChain) {
9080 assert(Subtarget.isPPC64() &&
9081 "i32->FP without LFIWAX supported only on PPC64");
9090 Chain, dl, Ext64, FIdx,
9096 MVT::f64, dl, Chain, FIdx,
9105 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9109 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9126 uint64_t
Mode = CVal->getZExtValue();
9127 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9128 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9129 if (Subtarget.isISA3_0())
9132 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9133 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9136 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9137 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9139 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9157 if (!Subtarget.isISA3_0()) {
9159 Chain =
MFFS.getValue(1);
9162 if (Subtarget.isPPC64()) {
9163 if (Subtarget.isISA3_0()) {
9168 PPC::RLDIMI, Dl, MVT::i64,
9169 {DAG.
getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
9173 NewFPSCR =
SDValue(InsertRN, 0);
9175 NewFPSCR = DAG.
getNode(ISD::BITCAST, Dl, MVT::f64, NewFPSCR);
9180 SDValue Addr = Subtarget.isLittleEndian()
9184 if (Subtarget.isISA3_0()) {
9185 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9187 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9189 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9192 PPC::RLWIMI, Dl, MVT::i32,
9193 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9194 DAG.getTargetConstant(30, Dl, MVT::i32),
9195 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9197 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9200 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9203 if (Subtarget.isISA3_0())
9209 PPC::MTFSF, Dl, MVT::Other,
9237 EVT VT =
Op.getValueType();
9243 Chain =
MFFS.getValue(1);
9248 DAG.
getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
9253 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9257 "Stack slot adjustment is valid only on big endian subtargets!");
9260 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9287 EVT VT =
Op.getValueType();
9291 VT ==
Op.getOperand(1).getValueType() &&
9311 SDValue OutOps[] = { OutLo, OutHi };
9316 EVT VT =
Op.getValueType();
9320 VT ==
Op.getOperand(1).getValueType() &&
9340 SDValue OutOps[] = { OutLo, OutHi };
9346 EVT VT =
Op.getValueType();
9349 VT ==
Op.getOperand(1).getValueType() &&
9369 SDValue OutOps[] = { OutLo, OutHi };
9376 EVT VT =
Op.getValueType();
9383 EVT AmtVT =
Z.getValueType();
9406 static const MVT VTys[] = {
9407 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9410 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9413 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9418 EVT CanonicalVT = VTys[SplatSize-1];
9431 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9432 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9441 EVT DestVT = MVT::Other) {
9442 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9451 EVT DestVT = MVT::Other) {
9454 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9466 for (
unsigned i = 0; i != 16; ++i)
9469 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9487 EVT VecVT = V->getValueType(0);
9488 bool RightType = VecVT == MVT::v2f64 ||
9489 (HasP8Vector && VecVT == MVT::v4f32) ||
9490 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9494 bool IsSplat =
true;
9495 bool IsLoad =
false;
9501 if (V->isConstant())
9503 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9504 if (V->getOperand(i).isUndef())
9508 if (V->getOperand(i).getOpcode() == ISD::LOAD ||
9510 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9512 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9514 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
9518 if (V->getOperand(i) != Op0 ||
9519 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9522 return !(IsSplat && IsLoad);
9532 (
Op.getValueType() != MVT::f128))
9537 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9540 if (!Subtarget.isLittleEndian())
9548 while (InputLoad->
getOpcode() == ISD::BITCAST)
9555 if (InputLoad->
getOpcode() != ISD::LOAD)
9565 APFloat APFloatToConvert = ArgAPFloat;
9566 bool LosesInfo =
true;
9571 ArgAPFloat = APFloatToConvert;
9593 APFloat APFloatToConvert = ArgAPFloat;
9594 bool LosesInfo =
true;
9598 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9607 EVT Ty =
Op->getValueType(0);
9610 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9619 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9623 if (Ty == MVT::v2i64) {
9626 if (MemVT == MVT::i32) {
9638 bool IsLittleEndian) {
9644 APInt ConstValue(VTSize, 0);
9648 unsigned BitPos = 0;
9656 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9657 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9661 for (
unsigned J = 0; J < 16; ++J) {
9663 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9665 if (ExtractValue == 0xFF)
9680 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9682 if (Subtarget.hasP10Vector()) {
9683 APInt BitMask(32, 0);
9689 BitMask != 0 && BitMask != 0xffff) {
9691 MachineSDNode *MSDNode =
9697 SDV = DAG.
getNode(ISD::BITCAST, dl, DVT, SDV);
9703 APInt APSplatBits, APSplatUndef;
9704 unsigned SplatBitSize;
9706 bool BVNIsConstantSplat =
9708 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9714 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9715 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9718 if ((
Op->getValueType(0) == MVT::v2f64) &&
9751 bool IsSplat64 =
false;
9752 uint64_t SplatBits = 0;
9753 int32_t SextVal = 0;
9754 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9756 if (SplatBitSize <= 32) {
9758 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9759 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9760 bool P9Vector = Subtarget.hasP9Vector();
9761 int32_t
Hi = P9Vector ? 127 : 15;
9762 int32_t
Lo = P9Vector ? -128 : -16;
9763 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9764 SextVal =
static_cast<int32_t
>(SplatBits);
9768 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9775 const SDValue *InputLoad = &
Op.getOperand(0);
9780 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9781 unsigned ElementSize =
9784 assert(((ElementSize == 2 * MemorySize)
9788 "Unmatched element size and opcode!\n");
9793 unsigned NumUsesOfInputLD = 128 / ElementSize;
9795 if (BVInOp.isUndef())
9810 if (NumUsesOfInputLD == 1 &&
9812 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9813 Subtarget.hasLFIWAX()))
9821 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9822 Subtarget.isISA3_1() && ElementSize <= 16)
9825 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9827 Subtarget.hasVSX()) {
9834 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9835 LD->getMemoryVT(),
LD->getMemOperand());
9847 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9849 Subtarget.hasP8Vector()))
9855 unsigned SplatSize = SplatBitSize / 8;
9860 if (SplatBits == 0) {
9862 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9864 Op = DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Z);
9874 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9876 Op.getValueType(), DAG, dl);
9878 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9883 if (Subtarget.hasP9Vector() && SplatSize == 1)
9889 if (SextVal >= -16 && SextVal <= 15) {
9892 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9902 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9908 switch (SplatSize) {
9912 IID = Intrinsic::ppc_altivec_vupklsb;
9916 IID = Intrinsic::ppc_altivec_vextsb2w;
9920 IID = Intrinsic::ppc_altivec_vextsb2d;
9927 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9936 if (SextVal >= -32 && SextVal <= 31) {
9941 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9942 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9945 if (VT ==
Op.getValueType())
9948 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), RetVal);
9954 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9964 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9968 static const signed char SplatCsts[] = {
9969 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9970 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9973 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9976 int i = SplatCsts[idx];
9980 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9983 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9985 static const unsigned IIDs[] = {
9986 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9987 Intrinsic::ppc_altivec_vslw
9990 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9994 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9996 static const unsigned IIDs[] = {
9997 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9998 Intrinsic::ppc_altivec_vsrw
10001 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
10005 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
10006 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
10008 static const unsigned IIDs[] = {
10009 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
10010 Intrinsic::ppc_altivec_vrlw
10013 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
10017 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
10019 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
10023 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10025 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
10029 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10031 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
10044 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10045 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10046 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10062 if (LHSID == (1*9+2)*9+3)
return LHS;
10063 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10075 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10076 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10077 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10078 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10081 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10082 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10083 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10084 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10087 for (
unsigned i = 0; i != 16; ++i)
10088 ShufIdxs[i] = (i&3)+0;
10091 for (
unsigned i = 0; i != 16; ++i)
10092 ShufIdxs[i] = (i&3)+4;
10095 for (
unsigned i = 0; i != 16; ++i)
10096 ShufIdxs[i] = (i&3)+8;
10099 for (
unsigned i = 0; i != 16; ++i)
10100 ShufIdxs[i] = (i&3)+12;
10110 OpLHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpLHS);
10111 OpRHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpRHS);
10113 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
10121 const unsigned BytesInVector = 16;
10122 bool IsLE = Subtarget.isLittleEndian();
10126 unsigned ShiftElts = 0, InsertAtByte = 0;
10130 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10131 0, 15, 14, 13, 12, 11, 10, 9};
10132 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10133 1, 2, 3, 4, 5, 6, 7, 8};
10135 ArrayRef<int>
Mask =
N->getMask();
10136 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10148 bool FoundCandidate =
false;
10152 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10155 for (
unsigned i = 0; i < BytesInVector; ++i) {
10156 unsigned CurrentElement =
Mask[i];
10159 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10162 bool OtherElementsInOrder =
true;
10165 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10172 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10173 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10174 OtherElementsInOrder =
false;
10181 if (OtherElementsInOrder) {
10188 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10189 : BigEndianShifts[CurrentElement & 0xF];
10190 Swap = CurrentElement < BytesInVector;
10192 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10193 FoundCandidate =
true;
10198 if (!FoundCandidate)
10222 const unsigned NumHalfWords = 8;
10223 const unsigned BytesInVector = NumHalfWords * 2;
10228 bool IsLE = Subtarget.isLittleEndian();
10232 unsigned ShiftElts = 0, InsertAtByte = 0;
10236 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10237 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10240 uint32_t OriginalOrderLow = 0x1234567;
10241 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10244 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10245 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10262 bool FoundCandidate =
false;
10265 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10266 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10268 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10269 uint32_t TargetOrder = 0x0;
10276 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10277 TargetOrder = OriginalOrderLow;
10281 if (MaskOneElt == VINSERTHSrcElem &&
10282 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10283 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10284 FoundCandidate =
true;
10290 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10292 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10294 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10295 : BigEndianShifts[MaskOneElt & 0x7];
10296 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10297 Swap = MaskOneElt < NumHalfWords;
10298 FoundCandidate =
true;
10304 if (!FoundCandidate)
10321 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10326 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10339 auto ShuffleMask = SVN->
getMask();
10354 ShuffleMask = CommutedSV->
getMask();
10363 APInt APSplatValue, APSplatUndef;
10364 unsigned SplatBitSize;
10367 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10379 bool IsLE = Subtarget.isLittleEndian();
10380 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10381 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10382 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10384 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10385 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10386 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10394 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10395 SplatVal |= (SplatVal << SplatBitSize);
10400 return DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8, SplatNode);
10409 assert(
Op.getValueType() == MVT::v1i128 &&
10410 "Only set v1i128 as custom, other type shouldn't reach here!");
10415 if (SHLAmt % 8 == 0) {
10416 std::array<int, 16>
Mask;
10417 std::iota(
Mask.begin(),
Mask.end(), 0);
10418 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10422 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, Shuffle);
10430 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, OROp);
10447 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10452 V1 =
Op.getOperand(0);
10453 V2 =
Op.getOperand(1);
10455 EVT VT =
Op.getValueType();
10456 bool isLittleEndian = Subtarget.isLittleEndian();
10458 unsigned ShiftElts, InsertAtByte;
10464 bool IsPermutedLoad =
false;
10466 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10476 if (IsPermutedLoad) {
10477 assert((isLittleEndian || IsFourByte) &&
10478 "Unexpected size for permuted load on big endian target");
10479 SplatIdx += IsFourByte ? 2 : 1;
10480 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10481 "Splat of a value outside of the loaded memory");
10486 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10489 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10491 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10495 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10508 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10511 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10520 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10523 if (Subtarget.hasP9Vector() &&
10537 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10541 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10544 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10546 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10547 return SplatInsertNode;
10550 if (Subtarget.hasP9Altivec()) {
10552 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10555 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10559 if (Subtarget.hasVSX() &&
10565 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, V2.
isUndef() ? V1 : V2);
10569 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
10572 if (Subtarget.hasVSX() &&
10578 DAG.
getNode(ISD::BITCAST, dl, MVT::v2i64, V2.isUndef() ? V1 : V2);
10582 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
10585 if (Subtarget.hasP9Vector()) {
10589 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveHWord);
10593 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveWord);
10597 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveDWord);
10601 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveQWord);
10605 if (Subtarget.hasVSX()) {
10612 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8,
Splat);
10619 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Swap);
10626 if (V2.isUndef()) {
10639 (Subtarget.hasP8Altivec() && (
10650 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10660 (Subtarget.hasP8Altivec() && (
10668 ArrayRef<int> PermMask = SVOp->
getMask();
10671 unsigned PFIndexes[4];
10672 bool isFourElementShuffle =
true;
10673 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10675 unsigned EltNo = 8;
10676 for (
unsigned j = 0;
j != 4; ++
j) {
10677 if (PermMask[i * 4 + j] < 0)
10680 unsigned ByteSource = PermMask[i * 4 +
j];
10681 if ((ByteSource & 3) != j) {
10682 isFourElementShuffle =
false;
10687 EltNo = ByteSource / 4;
10688 }
else if (EltNo != ByteSource / 4) {
10689 isFourElementShuffle =
false;
10693 PFIndexes[i] = EltNo;
10701 if (isFourElementShuffle) {
10703 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10704 PFIndexes[2] * 9 + PFIndexes[3];
10707 unsigned Cost = (PFEntry >> 30);
10727 if (V2.isUndef()) V2 = V1;
10729 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10738 bool NeedSwap =
false;
10739 bool isLittleEndian = Subtarget.isLittleEndian();
10740 bool isPPC64 = Subtarget.isPPC64();
10742 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10744 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10745 "XXPERM instead\n");
10754 NeedSwap = !NeedSwap;
10789 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10791 if (V1HasXXSWAPD) {
10794 else if (SrcElt < 16)
10797 if (V2HasXXSWAPD) {
10800 else if (SrcElt > 15)
10809 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10810 if (isLittleEndian)
10812 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10815 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10818 if (V1HasXXSWAPD) {
10822 if (V2HasXXSWAPD) {
10827 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10828 if (ValType != MVT::v2f64)
10834 ShufflesHandledWithVPERM++;
10839 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10841 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10844 dbgs() <<
"With the following permute control vector:\n";
10849 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10853 if (isLittleEndian)
10859 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10871 switch (IntrinsicID) {
10875 case Intrinsic::ppc_altivec_vcmpbfp_p:
10879 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10883 case Intrinsic::ppc_altivec_vcmpequb_p:
10887 case Intrinsic::ppc_altivec_vcmpequh_p:
10891 case Intrinsic::ppc_altivec_vcmpequw_p:
10895 case Intrinsic::ppc_altivec_vcmpequd_p:
10896 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10902 case Intrinsic::ppc_altivec_vcmpneb_p:
10903 case Intrinsic::ppc_altivec_vcmpneh_p:
10904 case Intrinsic::ppc_altivec_vcmpnew_p:
10905 case Intrinsic::ppc_altivec_vcmpnezb_p:
10906 case Intrinsic::ppc_altivec_vcmpnezh_p:
10907 case Intrinsic::ppc_altivec_vcmpnezw_p:
10908 if (Subtarget.hasP9Altivec()) {
10909 switch (IntrinsicID) {
10912 case Intrinsic::ppc_altivec_vcmpneb_p:
10915 case Intrinsic::ppc_altivec_vcmpneh_p:
10918 case Intrinsic::ppc_altivec_vcmpnew_p:
10921 case Intrinsic::ppc_altivec_vcmpnezb_p:
10924 case Intrinsic::ppc_altivec_vcmpnezh_p:
10927 case Intrinsic::ppc_altivec_vcmpnezw_p:
10935 case Intrinsic::ppc_altivec_vcmpgefp_p:
10939 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10943 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10947 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10951 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10955 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10956 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10962 case Intrinsic::ppc_altivec_vcmpgtub_p:
10966 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10970 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10974 case Intrinsic::ppc_altivec_vcmpgtud_p:
10975 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10982 case Intrinsic::ppc_altivec_vcmpequq:
10983 case Intrinsic::ppc_altivec_vcmpgtsq:
10984 case Intrinsic::ppc_altivec_vcmpgtuq:
10985 if (!Subtarget.isISA3_1())
10987 switch (IntrinsicID) {
10990 case Intrinsic::ppc_altivec_vcmpequq:
10993 case Intrinsic::ppc_altivec_vcmpgtsq:
10996 case Intrinsic::ppc_altivec_vcmpgtuq:
11003 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11004 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11005 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11006 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11007 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11008 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11009 if (Subtarget.hasVSX()) {
11010 switch (IntrinsicID) {
11011 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11014 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11017 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11020 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11023 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11026 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11036 case Intrinsic::ppc_altivec_vcmpbfp:
11039 case Intrinsic::ppc_altivec_vcmpeqfp:
11042 case Intrinsic::ppc_altivec_vcmpequb:
11045 case Intrinsic::ppc_altivec_vcmpequh:
11048 case Intrinsic::ppc_altivec_vcmpequw:
11051 case Intrinsic::ppc_altivec_vcmpequd:
11052 if (Subtarget.hasP8Altivec())
11057 case Intrinsic::ppc_altivec_vcmpneb:
11058 case Intrinsic::ppc_altivec_vcmpneh:
11059 case Intrinsic::ppc_altivec_vcmpnew:
11060 case Intrinsic::ppc_altivec_vcmpnezb:
11061 case Intrinsic::ppc_altivec_vcmpnezh:
11062 case Intrinsic::ppc_altivec_vcmpnezw:
11063 if (Subtarget.hasP9Altivec())
11064 switch (IntrinsicID) {
11067 case Intrinsic::ppc_altivec_vcmpneb:
11070 case Intrinsic::ppc_altivec_vcmpneh:
11073 case Intrinsic::ppc_altivec_vcmpnew:
11076 case Intrinsic::ppc_altivec_vcmpnezb:
11079 case Intrinsic::ppc_altivec_vcmpnezh:
11082 case Intrinsic::ppc_altivec_vcmpnezw:
11089 case Intrinsic::ppc_altivec_vcmpgefp:
11092 case Intrinsic::ppc_altivec_vcmpgtfp:
11095 case Intrinsic::ppc_altivec_vcmpgtsb:
11098 case Intrinsic::ppc_altivec_vcmpgtsh:
11101 case Intrinsic::ppc_altivec_vcmpgtsw:
11104 case Intrinsic::ppc_altivec_vcmpgtsd:
11105 if (Subtarget.hasP8Altivec())
11110 case Intrinsic::ppc_altivec_vcmpgtub:
11113 case Intrinsic::ppc_altivec_vcmpgtuh:
11116 case Intrinsic::ppc_altivec_vcmpgtuw:
11119 case Intrinsic::ppc_altivec_vcmpgtud:
11120 if (Subtarget.hasP8Altivec())
11125 case Intrinsic::ppc_altivec_vcmpequq_p:
11126 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11127 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11128 if (!Subtarget.isISA3_1())
11130 switch (IntrinsicID) {
11133 case Intrinsic::ppc_altivec_vcmpequq_p:
11136 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11139 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11153 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11157 switch (IntrinsicID) {
11158 case Intrinsic::thread_pointer:
11160 if (Subtarget.isPPC64())
11164 case Intrinsic::ppc_rldimi: {
11165 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11167 APInt
Mask =
Op.getConstantOperandAPInt(4);
11169 return Op.getOperand(2);
11170 if (
Mask.isAllOnes())
11172 uint64_t SH =
Op.getConstantOperandVal(3);
11173 unsigned MB = 0, ME = 0;
11177 if (ME < 63 - SH) {
11180 }
else if (ME > 63 - SH) {
11186 {Op.getOperand(2), Src,
11187 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11188 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11192 case Intrinsic::ppc_rlwimi: {
11193 APInt
Mask =
Op.getConstantOperandAPInt(4);
11195 return Op.getOperand(2);
11196 if (
Mask.isAllOnes())
11199 unsigned MB = 0, ME = 0;
11203 PPC::RLWIMI, dl, MVT::i32,
11204 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11205 DAG.getTargetConstant(MB, dl, MVT::i32),
11206 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11210 case Intrinsic::ppc_rlwnm: {
11211 if (
Op.getConstantOperandVal(3) == 0)
11213 unsigned MB = 0, ME = 0;
11218 {Op.getOperand(1), Op.getOperand(2),
11219 DAG.getTargetConstant(MB, dl, MVT::i32),
11220 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11224 case Intrinsic::ppc_mma_disassemble_acc: {
11225 if (Subtarget.isISAFuture()) {
11226 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11238 Subtarget.isLittleEndian() ? Value2 :
Value,
11239 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11244 Subtarget.isLittleEndian() ? Value2 :
Value,
11245 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11250 Subtarget.isLittleEndian() ?
Value : Value2,
11251 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11256 Subtarget.isLittleEndian() ?
Value : Value2,
11257 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11264 case Intrinsic::ppc_vsx_disassemble_pair: {
11267 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11272 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11275 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11283 case Intrinsic::ppc_mma_build_dmr: {
11286 for (
int i = 1; i < 9; i += 2) {
11289 if (
Hi->getOpcode() == ISD::LOAD)
11291 if (
Lo->getOpcode() == ISD::LOAD)
11301 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11302 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11304 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11305 "Specify P of 0 or 1 for lower or upper 512 bytes");
11306 unsigned HiLo = Idx->getSExtValue();
11310 Opcode = PPC::DMXXEXTFDMR512;
11311 Subx = PPC::sub_wacc_lo;
11313 Opcode = PPC::DMXXEXTFDMR512_HI;
11314 Subx = PPC::sub_wacc_hi;
11317 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11321 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11325 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11326 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11328 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11329 "Specify a dmr row pair 0-3");
11330 unsigned IdxVal = Idx->getSExtValue();
11334 Subx = PPC::sub_dmrrowp0;
11337 Subx = PPC::sub_dmrrowp1;
11340 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11343 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11347 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11353 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11357 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11358 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11360 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11361 "Specify P of 0 or 1 for lower or upper 512 bytes");
11362 unsigned HiLo = Idx->getSExtValue();
11366 Opcode = PPC::DMXXINSTDMR512;
11367 Subx = PPC::sub_wacc_lo;
11369 Opcode = PPC::DMXXINSTDMR512_HI;
11370 Subx = PPC::sub_wacc_hi;
11380 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11381 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11383 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11384 "Specify a dmr row pair 0-3");
11385 unsigned IdxVal = Idx->getSExtValue();
11389 Subx = PPC::sub_dmrrowp0;
11392 Subx = PPC::sub_dmrrowp1;
11395 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11398 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11407 Op.getOperand(1), DMRRowp,
SubReg),
11411 case Intrinsic::ppc_mma_xxmfacc:
11412 case Intrinsic::ppc_mma_xxmtacc: {
11414 if (!Subtarget.isISAFuture())
11425 case Intrinsic::ppc_unpack_longdouble: {
11427 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11428 "Argument of long double unpack must be 0 or 1!");
11431 Idx->getValueType(0)));
11434 case Intrinsic::ppc_compare_exp_lt:
11435 case Intrinsic::ppc_compare_exp_gt:
11436 case Intrinsic::ppc_compare_exp_eq:
11437 case Intrinsic::ppc_compare_exp_uo: {
11439 switch (IntrinsicID) {
11440 case Intrinsic::ppc_compare_exp_lt:
11443 case Intrinsic::ppc_compare_exp_gt:
11446 case Intrinsic::ppc_compare_exp_eq:
11449 case Intrinsic::ppc_compare_exp_uo:
11455 PPC::SELECT_CC_I4, dl, MVT::i32,
11456 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11457 Op.getOperand(1), Op.getOperand(2)),
11459 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11460 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11463 case Intrinsic::ppc_test_data_class: {
11464 EVT OpVT =
Op.getOperand(1).getValueType();
11465 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11466 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11470 PPC::SELECT_CC_I4, dl, MVT::i32,
11471 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11474 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11475 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11478 case Intrinsic::ppc_fnmsub: {
11479 EVT VT =
Op.getOperand(1).getValueType();
11480 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11484 DAG.
getNode(ISD::FNEG, dl, VT,
Op.getOperand(3))));
11486 Op.getOperand(2),
Op.getOperand(3));
11488 case Intrinsic::ppc_convert_f128_to_ppcf128:
11489 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11490 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11491 ? RTLIB::CONVERT_PPCF128_F128
11492 : RTLIB::CONVERT_F128_PPCF128;
11494 std::pair<SDValue, SDValue>
Result =
11495 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11499 case Intrinsic::ppc_maxfe:
11500 case Intrinsic::ppc_maxfl:
11501 case Intrinsic::ppc_maxfs:
11502 case Intrinsic::ppc_minfe:
11503 case Intrinsic::ppc_minfl:
11504 case Intrinsic::ppc_minfs: {
11505 EVT VT =
Op.getValueType();
11508 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11509 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11512 if (IntrinsicID == Intrinsic::ppc_minfe ||
11513 IntrinsicID == Intrinsic::ppc_minfl ||
11514 IntrinsicID == Intrinsic::ppc_minfs)
11536 Op.getOperand(1),
Op.getOperand(2),
11538 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Tmp);
11547 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11555 switch (
Op.getConstantOperandVal(1)) {
11560 Bitx = PPC::sub_eq;
11566 Bitx = PPC::sub_eq;
11572 Bitx = PPC::sub_lt;
11578 Bitx = PPC::sub_lt;
11584 if (Subtarget.isISA3_1()) {
11589 CR6Reg, SubRegIdx, GlueOp),
11591 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11619 switch (
Op.getConstantOperandVal(ArgStart)) {
11620 case Intrinsic::ppc_cfence: {
11621 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11622 SDValue Val =
Op.getOperand(ArgStart + 1);
11624 if (Ty == MVT::i128) {
11629 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11632 Opcode,
DL, MVT::Other,
11637 case Intrinsic::ppc_mma_disassemble_dmr: {
11639 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11650 if (!Subtarget.isPPC64())
11658 int VectorIndex = 0;
11659 if (Subtarget.isLittleEndian())
11670 assert(
Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
11671 "Expecting an atomic compare-and-swap here.");
11674 EVT MemVT = AtomicNode->getMemoryVT();
11692 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11693 Ops.push_back(AtomicNode->getOperand(i));
11695 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11696 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11705 EVT MemVT =
N->getMemoryVT();
11707 "Expect quadword atomic operations");
11709 unsigned Opc =
N->getOpcode();
11711 case ISD::ATOMIC_LOAD: {
11714 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11717 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11718 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11719 Ops.push_back(
N->getOperand(
I));
11721 Ops, MemVT,
N->getMemOperand());
11728 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11732 case ISD::ATOMIC_STORE: {
11735 SDVTList Tys = DAG.
getVTList(MVT::Other);
11738 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11744 Ops.push_back(ValLo);
11745 Ops.push_back(ValHi);
11746 Ops.push_back(
N->getOperand(2));
11748 N->getMemOperand());
11760 enum DataClassMask {
11762 DC_NEG_INF = 1 << 4,
11763 DC_POS_INF = 1 << 5,
11764 DC_NEG_ZERO = 1 << 2,
11765 DC_POS_ZERO = 1 << 3,
11766 DC_NEG_SUBNORM = 1,
11767 DC_POS_SUBNORM = 1 << 1,
11770 EVT VT =
Op.getValueType();
11772 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11773 : VT == MVT::f64 ? PPC::XSTSTDCDP
11784 return DAG.
getNOT(Dl, Rev, MVT::i1);
11791 TestOp, Dl, MVT::i32,
11793 DC_NEG_ZERO | DC_POS_ZERO |
11794 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11800 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11806 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11811 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11824 bool IsQuiet = Mask &
fcQNan;
11830 if (VT == MVT::f128) {
11834 QuietMask = 0x8000;
11835 }
else if (VT == MVT::f64) {
11836 if (Subtarget.isPPC64()) {
11847 QuietMask = 0x80000;
11848 }
else if (VT == MVT::f32) {
11850 QuietMask = 0x400000;
11866 unsigned NativeMask = 0;
11868 NativeMask |= DC_NAN;
11870 NativeMask |= DC_NEG_INF;
11872 NativeMask |= DC_POS_INF;
11874 NativeMask |= DC_NEG_ZERO;
11876 NativeMask |= DC_POS_ZERO;
11878 NativeMask |= DC_NEG_SUBNORM;
11880 NativeMask |= DC_POS_SUBNORM;
11883 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11885 TestOp, Dl, MVT::i32,
11894 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11896 uint64_t RHSC =
Op.getConstantOperandVal(1);
11899 if (
LHS.getValueType() == MVT::ppcf128) {
11915 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11917 int64_t
IntVal =
Op.getConstantOperandVal(0);
11918 if (IntVal >= -16 && IntVal <= 15)
11924 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11925 Op.getValueType() == MVT::v4i32 && Op0.
getOpcode() == ISD::LOAD &&
11929 MachineMemOperand *MMO =
11931 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11938 return Bits.getValue(0);
11954 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
11959 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11966 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11967 MachinePointerInfo());
11974 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
11980 "Should only be called for ISD::INSERT_VECTOR_ELT");
11984 EVT VT =
Op.getValueType();
11989 if (VT == MVT::v2f64 &&
C)
11992 if (Subtarget.hasP9Vector()) {
12001 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12007 BitcastLoad,
Op.getOperand(2));
12008 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12012 if (Subtarget.isISA3_1()) {
12013 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12017 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12018 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12028 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12031 unsigned InsertAtElement =
C->getZExtValue();
12032 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12033 if (Subtarget.isLittleEndian()) {
12034 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12048 EVT VT =
Op.getValueType();
12049 bool IsV1024i1 = VT == MVT::v1024i1;
12050 bool IsV2048i1 = VT == MVT::v2048i1;
12054 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12056 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12057 "Dense Math support required.");
12058 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12067 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12068 MachineMemOperand *NewMMO =
12076 DAG.
getVTList(MVT::v256i1, MVT::Other),
12077 LoadOps, MVT::v256i1, NewMMO);
12082 if (Subtarget.isLittleEndian()) {
12083 std::reverse(Loads.
begin(), Loads.
end());
12084 std::reverse(LoadChains.
begin(), LoadChains.
end());
12093 Loads[2], Loads[3]),
12109 Loads[4], Loads[5]),
12112 Loads[6], Loads[7]),
12114 const SDValue Dmr1Ops[] = {RC, Dmr1Lo, LoSub, Dmr1Hi, HiSub};
12116 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Dmr1Ops), 0);
12122 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12125 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12138 Pairs[2], Pairs[3]),
12144 {RC, Lo, LoSub, Hi, HiSub}),
12154 EVT VT =
Op.getValueType();
12156 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12157 return LowerDMFVectorLoad(
Op, DAG);
12159 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12165 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12166 "Type unsupported without MMA");
12167 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12168 "Type unsupported without paired vector support");
12173 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12175 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12184 if (Subtarget.isLittleEndian()) {
12185 std::reverse(Loads.
begin(), Loads.
end());
12186 std::reverse(LoadChains.
begin(), LoadChains.
end());
12206 bool IsV1024i1 = VT == MVT::v1024i1;
12207 bool IsV2048i1 = VT == MVT::v2048i1;
12211 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12213 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12214 "Dense Math support required.");
12215 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12217 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12220 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12225 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12229 MachineSDNode *ExtNode =
12233 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12239 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12245 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12251 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12256 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12261 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12266 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12270 MachineSDNode *ExtNode =
12271 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12275 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12278 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12282 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12287 if (Subtarget.isLittleEndian())
12288 std::reverse(Values.
begin(), Values.
end());
12290 SDVTList Tys = DAG.
getVTList(MVT::Other);
12292 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12296 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12297 MachineMemOperand *NewMMO =
12304 Ops[2] = Values[Idx];
12306 MVT::v256i1, NewMMO);
12322 EVT StoreVT =
Value.getValueType();
12324 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12325 return LowerDMFVectorStore(
Op, DAG);
12327 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12333 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12334 "Type unsupported without MMA");
12335 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12336 "Type unsupported without paired vector support");
12339 unsigned NumVecs = 2;
12340 if (StoreVT == MVT::v512i1) {
12341 if (Subtarget.isISAFuture()) {
12342 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12344 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12347 Value2 =
SDValue(ExtNode, 1);
12352 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12353 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12355 if (Subtarget.isISAFuture()) {
12356 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12358 Idx > 1 ? Value2 :
Value,
12365 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12379 if (
Op.getValueType() == MVT::v4i32) {
12391 RHSSwap = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHSSwap);
12396 LHS,
RHS, DAG, dl, MVT::v4i32);
12399 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12404 }
else if (
Op.getValueType() == MVT::v16i8) {
12406 bool isLittleEndian = Subtarget.isLittleEndian();
12410 LHS,
RHS, DAG, dl, MVT::v8i16);
12411 EvenParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, EvenParts);
12415 LHS,
RHS, DAG, dl, MVT::v8i16);
12416 OddParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OddParts);
12423 for (
unsigned i = 0; i != 8; ++i) {
12424 if (isLittleEndian) {
12426 Ops[i*2+1] = 2*i+16;
12429 Ops[i*2+1] = 2*i+1+16;
12432 if (isLittleEndian)
12442 bool IsStrict =
Op->isStrictFPOpcode();
12443 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12444 !Subtarget.hasP9Vector())
12453 assert(
Op.getOpcode() == ISD::FP_EXTEND &&
12454 "Should only be called for ISD::FP_EXTEND");
12458 if (
Op.getValueType() != MVT::v2f64 ||
12459 Op.getOperand(0).getValueType() != MVT::v2f32)
12471 "Node should have 2 operands with second one being a constant!");
12483 int DWord = Idx >> 1;
12486 if (Subtarget.isLittleEndian())
12503 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12506 LD->getMemoryVT(),
LD->getMemOperand());
12516 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12519 LD->getMemoryVT(),
LD->getMemOperand());
12531 if (STI.useCRBits())
12549 if (STI.useCRBits())
12557 SDNode *
N =
Op.getNode();
12558 EVT VT =
N->getValueType(0);
12559 EVT CarryType =
N->getValueType(1);
12560 unsigned Opc =
N->getOpcode();
12564 N->getOperand(0),
N->getOperand(1));
12576 SDNode *
N =
Op.getNode();
12577 unsigned Opc =
N->getOpcode();
12578 EVT VT =
N->getValueType(0);
12579 EVT CarryType =
N->getValueType(1);
12580 SDValue CarryOp =
N->getOperand(2);
12588 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12602 EVT VT =
Op.getNode()->getValueType(0);
12624 switch (
Op.getOpcode()) {
12627 case ISD::FPOW:
return lowerPow(
Op, DAG);
12628 case ISD::FSIN:
return lowerSin(
Op, DAG);
12629 case ISD::FCOS:
return lowerCos(
Op, DAG);
12630 case ISD::FLOG:
return lowerLog(
Op, DAG);
12631 case ISD::FLOG10:
return lowerLog10(
Op, DAG);
12632 case ISD::FEXP:
return lowerExp(
Op, DAG);
12641 case ISD::INIT_TRAMPOLINE:
return LowerINIT_TRAMPOLINE(
Op, DAG);
12642 case ISD::ADJUST_TRAMPOLINE:
return LowerADJUST_TRAMPOLINE(
Op, DAG);
12644 return LowerSSUBO(
Op, DAG);
12646 case ISD::INLINEASM:
12647 case ISD::INLINEASM_BR:
return LowerINLINEASM(
Op, DAG);
12649 case ISD::VASTART:
return LowerVASTART(
Op, DAG);
12650 case ISD::VAARG:
return LowerVAARG(
Op, DAG);
12651 case ISD::VACOPY:
return LowerVACOPY(
Op, DAG);
12653 case ISD::STACKRESTORE:
return LowerSTACKRESTORE(
Op, DAG);
12654 case ISD::DYNAMIC_STACKALLOC:
return LowerDYNAMIC_STACKALLOC(
Op, DAG);
12655 case ISD::GET_DYNAMIC_AREA_OFFSET:
12656 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12663 case ISD::LOAD:
return LowerLOAD(
Op, DAG);
12664 case ISD::STORE:
return LowerSTORE(
Op, DAG);
12676 case ISD::SET_ROUNDING:
12677 return LowerSET_ROUNDING(
Op, DAG);
12684 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12685 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12694 case ISD::FP_EXTEND:
return LowerFP_EXTEND(
Op, DAG);
12697 return LowerFP_ROUND(
Op, DAG);
12703 case ISD::BITCAST:
return LowerBITCAST(
Op, DAG);
12710 return LowerINTRINSIC_VOID(
Op, DAG);
12712 return LowerBSWAP(
Op, DAG);
12713 case ISD::ATOMIC_CMP_SWAP:
12714 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12715 case ISD::ATOMIC_STORE:
12716 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12718 return LowerIS_FPCLASS(
Op, DAG);
12721 return LowerADDSUBO(
Op, DAG);
12724 return LowerADDSUBO_CARRY(
Op, DAG);
12732 switch (
N->getOpcode()) {
12734 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12735 case ISD::ATOMIC_LOAD: {
12741 case ISD::READCYCLECOUNTER: {
12751 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12754 assert(
N->getValueType(0) == MVT::i1 &&
12755 "Unexpected result type for CTR decrement intrinsic");
12757 N->getValueType(0));
12767 switch (
N->getConstantOperandVal(0)) {
12768 case Intrinsic::ppc_pack_longdouble:
12770 N->getOperand(2),
N->getOperand(1)));
12772 case Intrinsic::ppc_maxfe:
12773 case Intrinsic::ppc_minfe:
12774 case Intrinsic::ppc_fnmsub:
12775 case Intrinsic::ppc_convert_f128_to_ppcf128:
12782 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12785 EVT VT =
N->getValueType(0);
12787 if (VT == MVT::i64) {
12800 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12804 Results.push_back(LoweredValue);
12805 if (
N->isStrictFPOpcode())
12810 if (!
N->getValueType(0).isVector())
12830 case ISD::FP_EXTEND:
12843 return Builder.CreateIntrinsic(Id, {});
12849 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12851 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12852 "Only 8/16/32/64-bit atomic loads supported");
12858 IntID = Intrinsic::ppc_lbarx;
12859 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12862 IntID = Intrinsic::ppc_lharx;
12863 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12866 IntID = Intrinsic::ppc_lwarx;
12869 IntID = Intrinsic::ppc_ldarx;
12873 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12875 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
12886 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12887 "Only 8/16/32/64-bit atomic loads supported");
12893 IntID = Intrinsic::ppc_stbcx;
12894 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12897 IntID = Intrinsic::ppc_sthcx;
12898 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12901 IntID = Intrinsic::ppc_stwcx;
12904 IntID = Intrinsic::ppc_stdcx;
12908 if (SZ == 8 || SZ == 16)
12909 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
12911 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
12913 return Builder.CreateXor(
Call, Builder.getInt32(1));
12936 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
12946 unsigned AtomicSize,
12947 unsigned BinOpcode,
12948 unsigned CmpOpcode,
12949 unsigned CmpPred)
const {
12953 auto LoadMnemonic = PPC::LDARX;
12954 auto StoreMnemonic = PPC::STDCX;
12955 switch (AtomicSize) {
12959 LoadMnemonic = PPC::LBARX;
12960 StoreMnemonic = PPC::STBCX;
12961 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12964 LoadMnemonic = PPC::LHARX;
12965 StoreMnemonic = PPC::STHCX;
12966 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12969 LoadMnemonic = PPC::LWARX;
12970 StoreMnemonic = PPC::STWCX;
12973 LoadMnemonic = PPC::LDARX;
12974 StoreMnemonic = PPC::STDCX;
12990 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12992 F->insert(It, loopMBB);
12994 F->insert(It, loop2MBB);
12995 F->insert(It, exitMBB);
13001 Register TmpReg = (!BinOpcode) ? incr :
13002 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13003 : &PPC::GPRCRegClass);
13028 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13033 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13035 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13036 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13037 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13065 switch(
MI.getOpcode()) {
13069 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13070 &
MI.getMF()->getRegInfo());
13094 case PPC::EXTSB8_32_64:
13095 case PPC::EXTSB8_rec:
13096 case PPC::EXTSB_rec:
13099 case PPC::EXTSH8_32_64:
13100 case PPC::EXTSH8_rec:
13101 case PPC::EXTSH_rec:
13103 case PPC::EXTSWSLI:
13104 case PPC::EXTSWSLI_32_64:
13105 case PPC::EXTSWSLI_32_64_rec:
13106 case PPC::EXTSWSLI_rec:
13107 case PPC::EXTSW_32:
13108 case PPC::EXTSW_32_64:
13109 case PPC::EXTSW_32_64_rec:
13110 case PPC::EXTSW_rec:
13113 case PPC::SRAWI_rec:
13114 case PPC::SRAW_rec:
13123 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13133 bool IsSignExtended =
13136 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13137 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13138 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13139 .
addReg(
MI.getOperand(3).getReg());
13140 MI.getOperand(3).setReg(ValueReg);
13144 if (Subtarget.hasPartwordAtomics())
13152 bool is64bit = Subtarget.isPPC64();
13153 bool isLittleEndian = Subtarget.isLittleEndian();
13154 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13165 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13167 F->insert(It, loopMBB);
13169 F->insert(It, loop2MBB);
13170 F->insert(It, exitMBB);
13176 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13179 Register PtrReg = RegInfo.createVirtualRegister(RC);
13180 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13182 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13183 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13184 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13185 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13186 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13187 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13188 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13189 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13190 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13191 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13194 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13221 if (ptrA != ZeroReg) {
13222 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13223 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13231 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13232 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13235 .
addImm(is8bit ? 28 : 27);
13236 if (!isLittleEndian)
13237 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13239 .
addImm(is8bit ? 24 : 16);
13241 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13246 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13256 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13260 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13265 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13269 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13272 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13279 Register SReg = RegInfo.createVirtualRegister(GPRC);
13280 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13284 unsigned ValueReg = SReg;
13285 unsigned CmpReg = Incr2Reg;
13286 if (CmpOpcode == PPC::CMPW) {
13287 ValueReg = RegInfo.createVirtualRegister(GPRC);
13288 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13291 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13292 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13294 ValueReg = ValueSReg;
13326 .
addImm(is8bit ? 24 : 16)
13347 Register DstReg =
MI.getOperand(0).getReg();
13349 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13350 Register mainDstReg =
MRI.createVirtualRegister(RC);
13351 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13354 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13355 "Invalid Pointer Size!");
13403 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13404 Register BufReg =
MI.getOperand(1).getReg();
13406 if (Subtarget.is64BitELFABI()) {
13419 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13421 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13424 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13447 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13450 if (Subtarget.isPPC64()) {
13468 TII->get(PPC::PHI), DstReg)
13472 MI.eraseFromParent();
13486 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13487 "Invalid Pointer Size!");
13490 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13493 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13494 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13508 Register BufReg =
MI.getOperand(0).getReg();
13513 if (PVT == MVT::i64) {
13525 if (PVT == MVT::i64) {
13537 if (PVT == MVT::i64) {
13549 if (PVT == MVT::i64) {
13561 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13571 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13574 MI.eraseFromParent();
13590 "Unexpected stack alignment");
13594 unsigned StackProbeSize =
13597 StackProbeSize &= ~(StackAlign - 1);
13598 return StackProbeSize ? StackProbeSize : StackAlign;
13610 const bool isPPC64 = Subtarget.isPPC64();
13642 MF->
insert(MBBIter, TestMBB);
13643 MF->
insert(MBBIter, BlockMBB);
13644 MF->
insert(MBBIter, TailMBB);
13649 Register DstReg =
MI.getOperand(0).getReg();
13650 Register NegSizeReg =
MI.getOperand(1).getReg();
13652 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13653 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13654 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13660 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13662 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13668 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13669 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13671 .
addDef(ActualNegSizeReg)
13673 .
add(
MI.getOperand(2))
13674 .
add(
MI.getOperand(3));
13680 .
addReg(ActualNegSizeReg);
13683 int64_t NegProbeSize = -(int64_t)ProbeSize;
13685 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13687 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13689 .
addImm(NegProbeSize >> 16);
13693 .
addImm(NegProbeSize & 0xFFFF);
13700 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13702 .
addReg(ActualNegSizeReg)
13704 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13708 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13711 .
addReg(ActualNegSizeReg);
13720 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13721 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13746 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13748 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13749 MaxCallFrameSizeReg)
13750 .
add(
MI.getOperand(2))
13751 .
add(
MI.getOperand(3));
13752 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13754 .
addReg(MaxCallFrameSizeReg);
13760 MBB->addSuccessor(TestMBB);
13763 MI.eraseFromParent();
13765 ++NumDynamicAllocaProbed;
13770 switch (
MI.getOpcode()) {
13771 case PPC::SELECT_CC_I4:
13772 case PPC::SELECT_CC_I8:
13773 case PPC::SELECT_CC_F4:
13774 case PPC::SELECT_CC_F8:
13775 case PPC::SELECT_CC_F16:
13776 case PPC::SELECT_CC_VRRC:
13777 case PPC::SELECT_CC_VSFRC:
13778 case PPC::SELECT_CC_VSSRC:
13779 case PPC::SELECT_CC_VSRC:
13780 case PPC::SELECT_CC_SPE4:
13781 case PPC::SELECT_CC_SPE:
13789 switch (
MI.getOpcode()) {
13790 case PPC::SELECT_I4:
13791 case PPC::SELECT_I8:
13792 case PPC::SELECT_F4:
13793 case PPC::SELECT_F8:
13794 case PPC::SELECT_F16:
13795 case PPC::SELECT_SPE:
13796 case PPC::SELECT_SPE4:
13797 case PPC::SELECT_VRRC:
13798 case PPC::SELECT_VSFRC:
13799 case PPC::SELECT_VSSRC:
13800 case PPC::SELECT_VSRC:
13810 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13811 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13812 if (Subtarget.is64BitELFABI() &&
13813 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13814 !Subtarget.isUsingPCRelativeCalls()) {
13826 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13827 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13829 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13830 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13844 if (Subtarget.hasISEL() &&
13845 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13846 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13847 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13849 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13850 MI.getOpcode() == PPC::SELECT_CC_I8)
13851 Cond.push_back(
MI.getOperand(4));
13854 Cond.push_back(
MI.getOperand(1));
13857 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13858 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13874 F->insert(It, copy0MBB);
13875 F->insert(It, sinkMBB);
13884 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13899 .
addReg(
MI.getOperand(1).getReg())
13902 unsigned SelectPred =
MI.getOperand(4).getImm();
13905 .
addReg(
MI.getOperand(1).getReg())
13922 .
addReg(
MI.getOperand(3).getReg())
13924 .
addReg(
MI.getOperand(2).getReg())
13926 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13942 F->insert(It, readMBB);
13943 F->insert(It, sinkMBB);
13954 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13962 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13964 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13974 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13976 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13978 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13980 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13983 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13985 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13987 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13989 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13992 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13994 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13996 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13998 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14001 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14003 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14005 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14007 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14010 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14012 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14014 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14016 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14019 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14021 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14023 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14025 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14028 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14030 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14032 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14034 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14037 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14039 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14041 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14043 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14046 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14048 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14050 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14052 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14055 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14057 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14059 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14061 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14064 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14066 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14068 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14070 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14072 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14073 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14074 (Subtarget.hasPartwordAtomics() &&
14075 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14076 (Subtarget.hasPartwordAtomics() &&
14077 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14078 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14080 auto LoadMnemonic = PPC::LDARX;
14081 auto StoreMnemonic = PPC::STDCX;
14082 switch (
MI.getOpcode()) {
14085 case PPC::ATOMIC_CMP_SWAP_I8:
14086 LoadMnemonic = PPC::LBARX;
14087 StoreMnemonic = PPC::STBCX;
14088 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14090 case PPC::ATOMIC_CMP_SWAP_I16:
14091 LoadMnemonic = PPC::LHARX;
14092 StoreMnemonic = PPC::STHCX;
14093 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14095 case PPC::ATOMIC_CMP_SWAP_I32:
14096 LoadMnemonic = PPC::LWARX;
14097 StoreMnemonic = PPC::STWCX;
14099 case PPC::ATOMIC_CMP_SWAP_I64:
14100 LoadMnemonic = PPC::LDARX;
14101 StoreMnemonic = PPC::STDCX;
14108 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14109 Register oldval =
MI.getOperand(3).getReg();
14110 Register newval =
MI.getOperand(4).getReg();
14116 F->insert(It, loop1MBB);
14117 F->insert(It, loop2MBB);
14118 F->insert(It, exitMBB);
14139 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14165 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14166 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14170 bool is64bit = Subtarget.isPPC64();
14171 bool isLittleEndian = Subtarget.isLittleEndian();
14172 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14177 Register oldval =
MI.getOperand(3).getReg();
14178 Register newval =
MI.getOperand(4).getReg();
14184 F->insert(It, loop1MBB);
14185 F->insert(It, loop2MBB);
14186 F->insert(It, exitMBB);
14193 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14196 Register PtrReg = RegInfo.createVirtualRegister(RC);
14197 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14199 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14200 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14201 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14202 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14203 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14204 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14205 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14206 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14207 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14208 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14209 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14211 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14212 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14213 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14244 if (ptrA != ZeroReg) {
14245 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14246 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14255 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14256 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
14259 .
addImm(is8bit ? 28 : 27);
14260 if (!isLittleEndian)
14261 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14263 .
addImm(is8bit ? 24 : 16);
14265 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14270 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14275 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14278 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14285 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14289 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14292 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14295 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14300 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14317 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14341 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14351 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14366 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14374 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14375 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14376 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14377 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14378 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14379 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14382 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14383 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14386 Register Dest = RegInfo.createVirtualRegister(
14387 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14391 .
addReg(
MI.getOperand(1).getReg())
14394 MI.getOperand(0).getReg())
14395 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14396 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14399 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14402 MI.getOperand(0).getReg())
14404 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14406 unsigned Imm =
MI.getOperand(1).getImm();
14409 MI.getOperand(0).getReg())
14411 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14413 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14416 if (
MRI.use_empty(OldFPSCRReg))
14417 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14419 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14430 unsigned Mode =
MI.getOperand(1).getImm();
14431 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14435 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14438 }
else if (
MI.getOpcode() == PPC::SETRND) {
14446 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14447 if (Subtarget.hasDirectMove()) {
14448 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14452 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14455 if (RC == &PPC::F8RCRegClass) {
14457 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14458 "Unsupported RegClass.");
14460 StoreOp = PPC::STFD;
14464 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14465 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14466 "Unsupported RegClass.");
14499 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14502 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14514 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14516 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14518 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14519 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14524 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14525 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14530 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14531 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14537 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14538 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14547 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14551 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14552 if (
MRI.use_empty(OldFPSCRReg))
14553 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14555 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14558 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14564 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14565 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14567 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14574 .
addUse(Src, 0, PPC::sub_gp8_x1);
14577 .
addUse(Src, 0, PPC::sub_gp8_x0);
14578 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14579 MI.getOpcode() == PPC::STQX_PSEUDO) {
14585 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14591 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14592 :
TII->get(PPC::STQ))
14600 MI.eraseFromParent();
14613 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14616 return RefinementSteps;
14622 EVT VT =
Op.getValueType();
14625 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14649PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14652 EVT VT =
Op.getValueType();
14653 if (VT != MVT::f64 &&
14654 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14661 int Enabled,
int &RefinementSteps,
14662 bool &UseOneConstNR,
14663 bool Reciprocal)
const {
14665 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14666 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14667 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14668 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14674 UseOneConstNR = !Subtarget.needsTwoConstNR();
14682 int &RefinementSteps)
const {
14684 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14685 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14686 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14687 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14706 switch (Subtarget.getCPUDirective()) {
14733 unsigned Bytes,
int Dist,
14747 if (FS != BFS || FS != (
int)Bytes)
return false;
14752 int64_t Offset1 = 0, Offset2 = 0;
14755 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14765 if (isGA1 && isGA2 && GV1 == GV2)
14766 return Offset1 == (Offset2 + Dist*Bytes);
14773 unsigned Bytes,
int Dist,
14776 EVT VT = LS->getMemoryVT();
14783 switch (
N->getConstantOperandVal(1)) {
14784 default:
return false;
14785 case Intrinsic::ppc_altivec_lvx:
14786 case Intrinsic::ppc_altivec_lvxl:
14787 case Intrinsic::ppc_vsx_lxvw4x:
14788 case Intrinsic::ppc_vsx_lxvw4x_be:
14791 case Intrinsic::ppc_vsx_lxvd2x:
14792 case Intrinsic::ppc_vsx_lxvd2x_be:
14795 case Intrinsic::ppc_altivec_lvebx:
14798 case Intrinsic::ppc_altivec_lvehx:
14801 case Intrinsic::ppc_altivec_lvewx:
14811 switch (
N->getConstantOperandVal(1)) {
14812 default:
return false;
14813 case Intrinsic::ppc_altivec_stvx:
14814 case Intrinsic::ppc_altivec_stvxl:
14815 case Intrinsic::ppc_vsx_stxvw4x:
14818 case Intrinsic::ppc_vsx_stxvd2x:
14821 case Intrinsic::ppc_vsx_stxvw4x_be:
14824 case Intrinsic::ppc_vsx_stxvd2x_be:
14827 case Intrinsic::ppc_altivec_stvebx:
14830 case Intrinsic::ppc_altivec_stvehx:
14833 case Intrinsic::ppc_altivec_stvewx:
14850 SDValue Chain = LD->getChain();
14851 EVT VT = LD->getMemoryVT();
14860 while (!Queue.empty()) {
14861 SDNode *ChainNext = Queue.pop_back_val();
14862 if (!Visited.
insert(ChainNext).second)
14869 if (!Visited.
count(ChainLD->getChain().getNode()))
14870 Queue.push_back(ChainLD->getChain().getNode());
14872 for (
const SDUse &O : ChainNext->
ops())
14873 if (!Visited.
count(O.getNode()))
14874 Queue.push_back(O.getNode());
14876 LoadRoots.
insert(ChainNext);
14887 for (
SDNode *
I : LoadRoots) {
14888 Queue.push_back(
I);
14890 while (!Queue.empty()) {
14891 SDNode *LoadRoot = Queue.pop_back_val();
14892 if (!Visited.
insert(LoadRoot).second)
14904 Queue.push_back(U);
14937 auto Final = Shifted;
14948 DAGCombinerInfo &DCI)
const {
14951 SelectionDAG &DAG = DCI.DAG;
14956 if (!DCI.isAfterLegalizeDAG())
14961 for (
const SDNode *U :
N->users())
14966 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14970 if (OpSize <
Size) {
14988 DAGCombinerInfo &DCI)
const {
14989 SelectionDAG &DAG = DCI.DAG;
14992 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15003 N->getValueType(0) != MVT::i1)
15006 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15007 N->getOperand(0).getValueType() != MVT::i64)
15017 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15028 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15051 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15052 N->getOperand(0).getOpcode() !=
ISD::OR &&
15053 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15063 N->getOperand(1).getOpcode() !=
ISD::AND &&
15064 N->getOperand(1).getOpcode() !=
ISD::OR &&
15065 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15076 SmallPtrSet<SDNode *, 16> Visited;
15078 for (
unsigned i = 0; i < 2; ++i) {
15082 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15094 while (!BinOps.
empty()) {
15102 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15136 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15140 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15141 if (User !=
N && !Visited.
count(User))
15150 if (
User->getOperand(0) == Inputs[i])
15153 if (
User->getOperand(0) == Inputs[i] ||
15154 User->getOperand(1) == Inputs[i])
15160 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15161 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15162 if (User !=
N && !Visited.
count(User))
15171 if (
User->getOperand(0) == PromOps[i])
15174 if (
User->getOperand(0) == PromOps[i] ||
15175 User->getOperand(1) == PromOps[i])
15182 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15191 std::list<HandleSDNode> PromOpHandles;
15192 for (
auto &PromOp : PromOps)
15193 PromOpHandles.emplace_back(PromOp);
15200 while (!PromOpHandles.empty()) {
15201 SDValue PromOp = PromOpHandles.back().getValue();
15202 PromOpHandles.pop_back();
15211 PromOpHandles.emplace_front(PromOp);
15225 default:
C = 0;
break;
15238 PromOpHandles.emplace_front(PromOp);
15245 for (
unsigned i = 0; i < 2; ++i)
15255 return N->getOperand(0);
15263 DAGCombinerInfo &DCI)
const {
15264 SelectionDAG &DAG = DCI.DAG;
15281 if (
N->getValueType(0) != MVT::i32 &&
15282 N->getValueType(0) != MVT::i64)
15285 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15286 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15289 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15290 N->getOperand(0).getOpcode() !=
ISD::OR &&
15291 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15298 SmallPtrSet<SDNode *, 16> Visited;
15302 while (!BinOps.
empty()) {
15310 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15336 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15341 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15346 if (User !=
N && !Visited.
count(User))
15352 if (
User->getOperand(0) == Inputs[i])
15353 SelectTruncOp[0].
insert(std::make_pair(User,
15354 User->getOperand(0).getValueType()));
15356 if (
User->getOperand(0) == Inputs[i])
15357 SelectTruncOp[0].
insert(std::make_pair(User,
15358 User->getOperand(0).getValueType()));
15359 if (
User->getOperand(1) == Inputs[i])
15360 SelectTruncOp[1].
insert(std::make_pair(User,
15361 User->getOperand(1).getValueType()));
15366 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15368 if (User !=
N && !Visited.
count(User))
15374 if (
User->getOperand(0) == PromOps[i])
15375 SelectTruncOp[0].
insert(std::make_pair(User,
15376 User->getOperand(0).getValueType()));
15378 if (
User->getOperand(0) == PromOps[i])
15379 SelectTruncOp[0].
insert(std::make_pair(User,
15380 User->getOperand(0).getValueType()));
15381 if (
User->getOperand(1) == PromOps[i])
15382 SelectTruncOp[1].
insert(std::make_pair(User,
15383 User->getOperand(1).getValueType()));
15388 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15389 bool ReallyNeedsExt =
false;
15393 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15398 Inputs[i].getOperand(0).getValueSizeInBits();
15399 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15404 OpBits-PromBits))) ||
15407 (OpBits-(PromBits-1)))) {
15408 ReallyNeedsExt =
true;
15416 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15423 SDValue InSrc = Inputs[i].getOperand(0);
15437 std::list<HandleSDNode> PromOpHandles;
15438 for (
auto &PromOp : PromOps)
15439 PromOpHandles.emplace_back(PromOp);
15445 while (!PromOpHandles.empty()) {
15447 PromOpHandles.pop_back();
15451 default:
C = 0;
break;
15464 PromOpHandles.emplace_front(PromOp);
15474 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15476 PromOpHandles.emplace_front(PromOp);
15484 for (
unsigned i = 0; i < 2; ++i) {
15502 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15503 if (SI0 != SelectTruncOp[0].
end())
15505 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15506 if (SI1 != SelectTruncOp[1].
end())
15515 if (!ReallyNeedsExt)
15516 return N->getOperand(0);
15523 N->getValueSizeInBits(0), PromBits),
15524 dl,
N->getValueType(0)));
15527 "Invalid extension type");
15530 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15538 DAGCombinerInfo &DCI)
const {
15540 "Should be called with a SETCC node");
15557 SelectionDAG &DAG = DCI.DAG;
15558 EVT VT =
N->getValueType(0);
15559 EVT OpVT =
LHS.getValueType();
15565 return DAGCombineTruncBoolExt(
N, DCI);
15572 Op.getValueType() == MVT::f64;
15584combineElementTruncationToVectorTruncation(
SDNode *
N,
15585 DAGCombinerInfo &DCI)
const {
15587 "Should be called with a BUILD_VECTOR node");
15589 SelectionDAG &DAG = DCI.DAG;
15592 SDValue FirstInput =
N->getOperand(0);
15594 "The input operand must be an fp-to-int conversion.");
15603 bool IsSplat =
true;
15608 EVT TargetVT =
N->getValueType(0);
15609 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15610 SDValue NextOp =
N->getOperand(i);
15614 if (NextConversion != FirstConversion)
15622 if (
N->getOperand(i) != FirstInput)
15633 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15634 SDValue In =
N->getOperand(i).getOperand(0);
15644 Ops.push_back(Trunc);
15647 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
15657 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15659 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15672 "Should be called with a BUILD_VECTOR node");
15677 if (!
N->getValueType(0).getVectorElementType().isByteSized())
15680 bool InputsAreConsecutiveLoads =
true;
15681 bool InputsAreReverseConsecutive =
true;
15682 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
15683 SDValue FirstInput =
N->getOperand(0);
15684 bool IsRoundOfExtLoad =
false;
15693 if ((!IsRoundOfExtLoad && FirstInput.
getOpcode() != ISD::LOAD) ||
15694 N->getNumOperands() == 1)
15697 if (!IsRoundOfExtLoad)
15702 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
15704 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
15707 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
15709 if (NextInput.
getOpcode() != ISD::LOAD)
15713 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
15724 InputsAreConsecutiveLoads =
false;
15726 InputsAreReverseConsecutive =
false;
15729 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15734 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15735 "The loads cannot be both consecutive and reverse consecutive.");
15739 if (InputsAreConsecutiveLoads) {
15740 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
15744 ReturnSDVal = WideLoad;
15745 }
else if (InputsAreReverseConsecutive) {
15747 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
15752 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
15760 for (
auto *LD : InputLoads)
15762 return ReturnSDVal;
15773 unsigned NumElems =
Input.getValueType().getVectorNumElements();
15779 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15781 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
15783 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
15784 CorrectElems = CorrectElems >> 8;
15785 Elems = Elems >> 8;
15792 EVT VT =
N->getValueType(0);
15796 Input.getValueType().getVectorElementType(),
15830 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
15856 Elems = Elems << 8;
15865 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15866 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15873 int TgtElemArrayIdx;
15874 int InputSize =
Input.getValueType().getScalarSizeInBits();
15875 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15876 if (InputSize + OutputSize == 40)
15877 TgtElemArrayIdx = 0;
15878 else if (InputSize + OutputSize == 72)
15879 TgtElemArrayIdx = 1;
15880 else if (InputSize + OutputSize == 48)
15881 TgtElemArrayIdx = 2;
15882 else if (InputSize + OutputSize == 80)
15883 TgtElemArrayIdx = 3;
15884 else if (InputSize + OutputSize == 96)
15885 TgtElemArrayIdx = 4;
15889 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15891 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15892 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15893 if (Elems != CorrectElems) {
15909 if (
N->getValueType(0) != MVT::v1i128)
15912 SDValue Operand =
N->getOperand(0);
15919 EVT MemoryType = LD->getMemoryVT();
15923 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15924 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15927 if (!ValidLDType ||
15933 LD->getChain(), LD->getBasePtr(),
15937 DAG.
getVTList(MVT::v1i128, MVT::Other),
15938 LoadOps, MemoryType, LD->getMemOperand());
15942 DAGCombinerInfo &DCI)
const {
15944 "Should be called with a BUILD_VECTOR node");
15946 SelectionDAG &DAG = DCI.DAG;
15949 if (!Subtarget.hasVSX())
15957 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15972 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15981 if (Subtarget.isISA3_1()) {
15987 if (
N->getValueType(0) != MVT::v2f64)
15998 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16009 if (!Ext1Op || !Ext2Op)
16018 if (FirstElem == 0 && SecondElem == 1)
16019 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16020 else if (FirstElem == 2 && SecondElem == 3)
16021 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16028 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16033 DAGCombinerInfo &DCI)
const {
16036 "Need an int -> FP conversion node here");
16041 SelectionDAG &DAG = DCI.DAG;
16047 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16049 if (!
Op.getOperand(0).getValueType().isSimple())
16051 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16052 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16055 SDValue FirstOperand(
Op.getOperand(0));
16056 bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
16057 (FirstOperand.getValueType() == MVT::i8 ||
16058 FirstOperand.getValueType() == MVT::i16);
16059 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16061 bool DstDouble =
Op.getValueType() == MVT::f64;
16062 unsigned ConvOp =
Signed ?
16069 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16072 Ops, MVT::i8, LDN->getMemOperand());
16077 SDValue ExtOps[] = { Ld, WidthConst };
16079 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16081 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16089 if (
Op.getOperand(0).getValueType() == MVT::i32)
16093 "UINT_TO_FP is supported only with FPCVT");
16097 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16102 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16109 Subtarget.hasFPCVT()) ||
16111 SDValue Src =
Op.getOperand(0).getOperand(0);
16112 if (Src.getValueType() == MVT::f32) {
16113 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
16114 DCI.AddToWorklist(Src.getNode());
16115 }
else if (Src.getValueType() != MVT::f64) {
16127 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16130 DCI.AddToWorklist(
FP.getNode());
16154 switch (
N->getOpcode()) {
16159 Chain = LD->getChain();
16160 Base = LD->getBasePtr();
16161 MMO = LD->getMemOperand();
16180 MVT VecTy =
N->getValueType(0).getSimpleVT();
16188 Chain = Load.getValue(1);
16194 if (VecTy != MVT::v2f64) {
16221 switch (
N->getOpcode()) {
16226 Chain = ST->getChain();
16227 Base = ST->getBasePtr();
16228 MMO = ST->getMemOperand();
16248 SDValue Src =
N->getOperand(SrcOpnd);
16249 MVT VecTy = Src.getValueType().getSimpleVT();
16252 if (VecTy != MVT::v2f64) {
16253 Src = DAG.
getNode(ISD::BITCAST, dl, MVT::v2f64, Src);
16258 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16264 StoreOps, VecTy, MMO);
16271 DAGCombinerInfo &DCI)
const {
16274 unsigned Opcode =
N->getOperand(1).getOpcode();
16276 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16280 &&
"Not a FP_TO_INT Instruction!");
16282 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16283 EVT Op1VT =
N->getOperand(1).getValueType();
16286 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16290 bool ValidTypeForStoreFltAsInt =
16291 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16292 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16295 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16298 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16306 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16321 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16322 for (
int i = 1, e = Mask.size(); i < e; i++) {
16323 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16325 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16327 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16338 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16339 FirstOp =
Op.getOperand(i);
16345 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16346 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16354 if (
Op.getOpcode() != ISD::BITCAST)
16356 Op =
Op.getOperand(0);
16372 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16373 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16375 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16377 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16378 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16379 int Idx = ShuffV[
I];
16380 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16381 ShuffV[
I] += LHSEltFixup;
16382 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16383 ShuffV[
I] += RHSEltFixup;
16394 SDLoc dl(OrigSToV);
16397 "Expecting a SCALAR_TO_VECTOR here");
16410 "Cannot produce a permuted scalar_to_vector for one element vector");
16412 unsigned ResultInElt = NumElts / 2;
16423 int HalfVec,
int LHSLastElementDefined,
16424 int RHSLastElementDefined) {
16425 for (
int Index : ShuffV) {
16429 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16430 (Index > LHSLastElementDefined))
16433 if ((RHSLastElementDefined >= 0) &&
16434 (Index > HalfVec + RHSLastElementDefined))
16441 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16442 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16458 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16459 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16462 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16463 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16464 return SToVPermuted;
16484 int NumElts =
LHS.getValueType().getVectorNumElements();
16487 bool IsLittleEndian = Subtarget.isLittleEndian();
16494 if (!Subtarget.hasDirectMove())
16510 SmallVector<int, 16> ShuffV(Mask);
16513 if (SToVLHS || SToVRHS) {
16516 int ShuffleNumElts = ShuffV.
size();
16517 int HalfVec = ShuffleNumElts / 2;
16523 unsigned LHSNumValidElts = HalfVec;
16524 unsigned RHSNumValidElts = HalfVec;
16529 int LHSFirstElt = 0;
16530 int RHSFirstElt = ShuffleNumElts;
16531 int LHSLastElt = -1;
16532 int RHSLastElt = -1;
16540 int LHSScalarSize = 0;
16541 int RHSScalarSize = 0;
16544 if (!IsLittleEndian && LHSScalarSize >= 64)
16549 if (!IsLittleEndian && RHSScalarSize >= 64)
16552 if (LHSScalarSize != 0)
16554 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
16555 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
16556 if (RHSScalarSize != 0)
16558 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
16559 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
16570 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
16571 LHSNumValidElts, RHSNumValidElts, Subtarget);
16597 if (IsLittleEndian) {
16600 if (Mask[0] < NumElts)
16601 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16605 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16610 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
16614 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
16619 if (Mask[0] < NumElts)
16620 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
16624 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
16629 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16633 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
16643 if (IsLittleEndian)
16652 DAGCombinerInfo &DCI)
const {
16654 "Not a reverse memop pattern!");
16656 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
16659 auto I =
Mask.rbegin();
16660 auto E =
Mask.rend();
16662 for (;
I !=
E; ++
I) {
16670 SelectionDAG &DAG = DCI.DAG;
16673 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
16679 if (!Subtarget.hasP9Vector())
16682 if(!IsElementReverse(SVN))
16685 if (LSBase->
getOpcode() == ISD::LOAD) {
16689 for (SDUse &Use : LSBase->
uses())
16690 if (
Use.getResNo() == 0 &&
16701 if (LSBase->
getOpcode() == ISD::STORE) {
16721 if (IntrinsicID == Intrinsic::ppc_stdcx)
16723 else if (IntrinsicID == Intrinsic::ppc_stwcx)
16725 else if (IntrinsicID == Intrinsic::ppc_sthcx)
16727 else if (IntrinsicID == Intrinsic::ppc_stbcx)
16753 switch (
N->getOpcode()) {
16756 return combineADD(
N, DCI);
16782 return combineSHL(
N, DCI);
16784 return combineSRA(
N, DCI);
16786 return combineSRL(
N, DCI);
16788 return combineMUL(
N, DCI);
16791 return combineFMALike(
N, DCI);
16794 return N->getOperand(0);
16798 return N->getOperand(0);
16804 return N->getOperand(0);
16810 return DAGCombineExtBoolTrunc(
N, DCI);
16812 return combineTRUNCATE(
N, DCI);
16814 if (
SDValue CSCC = combineSetCC(
N, DCI))
16818 return DAGCombineTruncBoolExt(
N, DCI);
16821 return combineFPToIntToFP(
N, DCI);
16830 EVT Op1VT =
N->getOperand(1).getValueType();
16831 unsigned Opcode =
N->getOperand(1).getOpcode();
16835 SDValue Val = combineStoreFPToInt(
N, DCI);
16849 N->getOperand(1).getNode()->hasOneUse() &&
16850 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
16851 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
16859 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
16866 if (Op1VT.
bitsGT(mVT)) {
16871 if (Op1VT == MVT::i64)
16876 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
16896 ST->getBasePtr(), ST->getOffset(), MemVT,
16897 ST->getMemOperand(), ST->getAddressingMode(),
16901 return ST->isUnindexed()
16910 if (Subtarget.needsSwapsForVSXMemOps() &&
16911 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
16912 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
16919 EVT VT = LD->getValueType(0);
16925 if (Subtarget.needsSwapsForVSXMemOps() &&
16926 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16927 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16938 auto ReplaceTwoFloatLoad = [&]() {
16939 if (VT != MVT::i64)
16954 if (!LD->hasNUsesOfValue(2, 0))
16957 auto UI = LD->user_begin();
16958 while (UI.getUse().getResNo() != 0) ++UI;
16960 while (UI.getUse().getResNo() != 0) ++UI;
16961 SDNode *RightShift = *UI;
16969 if (RightShift->getOpcode() !=
ISD::SRL ||
16971 RightShift->getConstantOperandVal(1) != 32 ||
16972 !RightShift->hasOneUse())
16975 SDNode *Trunc2 = *RightShift->user_begin();
16984 if (Bitcast->getOpcode() != ISD::BITCAST ||
16985 Bitcast->getValueType(0) != MVT::f32)
16987 if (Bitcast2->
getOpcode() != ISD::BITCAST ||
16991 if (Subtarget.isLittleEndian())
16997 SDValue BasePtr = LD->getBasePtr();
16998 if (LD->isIndexed()) {
17000 "Non-pre-inc AM on PPC?");
17008 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17009 LD->getPointerInfo(), LD->getAlign(),
17010 MMOFlags, LD->getAAInfo());
17016 LD->getPointerInfo().getWithOffset(4),
17019 if (LD->isIndexed()) {
17033 if (ReplaceTwoFloatLoad())
17036 EVT MemVT = LD->getMemoryVT();
17039 if (LD->isUnindexed() && VT.
isVector() &&
17042 !Subtarget.hasP8Vector() &&
17043 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17044 VT == MVT::v4f32))) &&
17045 LD->getAlign() < ABIAlignment) {
17047 SDValue Chain = LD->getChain();
17049 bool isLittleEndian = Subtarget.isLittleEndian();
17076 MVT PermCntlTy, PermTy, LDTy;
17077 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17078 : Intrinsic::ppc_altivec_lvsl;
17079 IntrLD = Intrinsic::ppc_altivec_lvx;
17080 IntrPerm = Intrinsic::ppc_altivec_vperm;
17081 PermCntlTy = MVT::v16i8;
17082 PermTy = MVT::v4i32;
17101 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
17105 BaseLoadOps, LDTy, BaseMMO);
17114 int IncValue = IncOffset;
17131 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
17135 ExtraLoadOps, LDTy, ExtraMMO);
17146 if (isLittleEndian)
17148 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17151 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17154 Perm = Subtarget.hasAltivec()
17155 ? DAG.
getNode(ISD::BITCAST, dl, VT, Perm)
17169 bool isLittleEndian = Subtarget.isLittleEndian();
17170 unsigned IID =
N->getConstantOperandVal(0);
17171 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17172 : Intrinsic::ppc_altivec_lvsl);
17173 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17180 .zext(
Add.getScalarValueSizeInBits()))) {
17181 SDNode *BasePtr =
Add->getOperand(0).getNode();
17182 for (
SDNode *U : BasePtr->users()) {
17184 U->getConstantOperandVal(0) == IID) {
17195 SDNode *BasePtr =
Add->getOperand(0).getNode();
17196 for (
SDNode *U : BasePtr->users()) {
17199 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17205 V->getConstantOperandVal(0) == IID) {
17217 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17218 IID == Intrinsic::ppc_altivec_vmaxsh ||
17219 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17250 switch (
N->getConstantOperandVal(1)) {
17253 case Intrinsic::ppc_altivec_vsum4sbs:
17254 case Intrinsic::ppc_altivec_vsum4shs:
17255 case Intrinsic::ppc_altivec_vsum4ubs: {
17262 APInt APSplatBits, APSplatUndef;
17263 unsigned SplatBitSize;
17266 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17267 !Subtarget.isLittleEndian());
17269 if (BVNIsConstantSplat && APSplatBits == 0)
17274 case Intrinsic::ppc_vsx_lxvw4x:
17275 case Intrinsic::ppc_vsx_lxvd2x:
17278 if (Subtarget.needsSwapsForVSXMemOps())
17286 if (Subtarget.needsSwapsForVSXMemOps()) {
17287 switch (
N->getConstantOperandVal(1)) {
17290 case Intrinsic::ppc_vsx_stxvw4x:
17291 case Intrinsic::ppc_vsx_stxvd2x:
17300 bool Is64BitBswapOn64BitTgt =
17301 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17303 N->getOperand(0).hasOneUse();
17304 if (IsSingleUseNormalLd &&
17305 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17306 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17317 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17318 MVT::i64 : MVT::i32, MVT::Other),
17319 Ops, LD->getMemoryVT(), LD->getMemOperand());
17323 if (
N->getValueType(0) == MVT::i16)
17340 !IsSingleUseNormalLd)
17345 if (!LD->isSimple())
17347 SDValue BasePtr = LD->getBasePtr();
17349 LD->getPointerInfo(), LD->getAlign());
17354 LD->getMemOperand(), 4, 4);
17358 if (Subtarget.isLittleEndian())
17364 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
17373 if (!
N->getOperand(0).hasOneUse() &&
17374 !
N->getOperand(1).hasOneUse() &&
17375 !
N->getOperand(2).hasOneUse()) {
17378 SDNode *VCMPrecNode =
nullptr;
17380 SDNode *LHSN =
N->getOperand(0).getNode();
17386 VCMPrecNode =
User;
17398 SDNode *FlagUser =
nullptr;
17400 FlagUser ==
nullptr; ++UI) {
17401 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
17414 return SDValue(VCMPrecNode, 0);
17425 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
17436 auto RHSAPInt = RHS->getAsAPIntVal();
17437 if (!RHSAPInt.isIntN(64))
17440 unsigned Val = RHSAPInt.getZExtValue();
17441 auto isImpossibleCompare = [&]() {
17444 if (Val != 0 && Val != 1) {
17446 return N->getOperand(0);
17448 return DAG.
getNode(ISD::BR, dl, MVT::Other,
17449 N->getOperand(0),
N->getOperand(4));
17454 unsigned StoreWidth = 0;
17457 if (
SDValue Impossible = isImpossibleCompare())
17469 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
17475 MemNode->getMemoryVT(), MemNode->getMemOperand());
17479 if (
N->getOperand(0) == LHS.getValue(1))
17492 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
17498 assert(isDot &&
"Can't compare against a vector result!");
17500 if (
SDValue Impossible = isImpossibleCompare())
17503 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
17510 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
17515 switch (LHS.getConstantOperandVal(1)) {
17534 N->getOperand(4), CompNode.
getValue(1));
17539 return DAGCombineBuildVector(
N, DCI);
17552 EVT VT =
N->getValueType(0);
17553 if (VT == MVT::i64 && !Subtarget.isPPC64())
17555 if ((VT != MVT::i32 && VT != MVT::i64) ||
17563 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
17583 const APInt &DemandedElts,
17585 unsigned Depth)
const {
17587 switch (
Op.getOpcode()) {
17592 Known.
Zero = 0xFFFF0000;
17596 if (
Op.getResNo() == 0) {
17601 Known.
Zero = ~1ULL;
17606 switch (
Op.getConstantOperandVal(0)) {
17608 case Intrinsic::ppc_altivec_vcmpbfp_p:
17609 case Intrinsic::ppc_altivec_vcmpeqfp_p:
17610 case Intrinsic::ppc_altivec_vcmpequb_p:
17611 case Intrinsic::ppc_altivec_vcmpequh_p:
17612 case Intrinsic::ppc_altivec_vcmpequw_p:
17613 case Intrinsic::ppc_altivec_vcmpequd_p:
17614 case Intrinsic::ppc_altivec_vcmpequq_p:
17615 case Intrinsic::ppc_altivec_vcmpgefp_p:
17616 case Intrinsic::ppc_altivec_vcmpgtfp_p:
17617 case Intrinsic::ppc_altivec_vcmpgtsb_p:
17618 case Intrinsic::ppc_altivec_vcmpgtsh_p:
17619 case Intrinsic::ppc_altivec_vcmpgtsw_p:
17620 case Intrinsic::ppc_altivec_vcmpgtsd_p:
17621 case Intrinsic::ppc_altivec_vcmpgtsq_p:
17622 case Intrinsic::ppc_altivec_vcmpgtub_p:
17623 case Intrinsic::ppc_altivec_vcmpgtuh_p:
17624 case Intrinsic::ppc_altivec_vcmpgtuw_p:
17625 case Intrinsic::ppc_altivec_vcmpgtud_p:
17626 case Intrinsic::ppc_altivec_vcmpgtuq_p:
17633 switch (
Op.getConstantOperandVal(1)) {
17636 case Intrinsic::ppc_load2r:
17638 Known.
Zero = 0xFFFF0000;
17647 switch (Subtarget.getCPUDirective()) {
17669 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
17678 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
17680 LoopSize +=
TII->getInstSizeInBytes(J);
17685 if (LoopSize > 16 && LoopSize <= 32)
17699 if (Constraint.
size() == 1) {
17700 switch (Constraint[0]) {
17718 }
else if (Constraint ==
"wc") {
17720 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
17721 Constraint ==
"wf" || Constraint ==
"ws" ||
17722 Constraint ==
"wi" || Constraint ==
"ww") {
17735 Value *CallOperandVal =
info.CallOperandVal;
17738 if (!CallOperandVal)
17745 else if ((
StringRef(constraint) ==
"wa" ||
17757 switch (*constraint) {
17787std::pair<unsigned, const TargetRegisterClass *>
17791 if (Constraint.
size() == 1) {
17793 switch (Constraint[0]) {
17795 if (VT == MVT::i64 && Subtarget.isPPC64())
17796 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
17797 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
17799 if (VT == MVT::i64 && Subtarget.isPPC64())
17800 return std::make_pair(0U, &PPC::G8RCRegClass);
17801 return std::make_pair(0U, &PPC::GPRCRegClass);
17807 if (Subtarget.hasSPE()) {
17808 if (VT == MVT::f32 || VT == MVT::i32)
17809 return std::make_pair(0U, &PPC::GPRCRegClass);
17810 if (VT == MVT::f64 || VT == MVT::i64)
17811 return std::make_pair(0U, &PPC::SPERCRegClass);
17813 if (VT == MVT::f32 || VT == MVT::i32)
17814 return std::make_pair(0U, &PPC::F4RCRegClass);
17815 if (VT == MVT::f64 || VT == MVT::i64)
17816 return std::make_pair(0U, &PPC::F8RCRegClass);
17820 if (Subtarget.hasAltivec() && VT.
isVector())
17821 return std::make_pair(0U, &PPC::VRRCRegClass);
17822 else if (Subtarget.hasVSX())
17824 return std::make_pair(0U, &PPC::VFRCRegClass);
17827 return std::make_pair(0U, &PPC::CRRCRegClass);
17829 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
17831 return std::make_pair(0U, &PPC::CRBITRCRegClass);
17832 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
17833 Constraint ==
"wf" || Constraint ==
"wi") &&
17834 Subtarget.hasVSX()) {
17838 return std::make_pair(0U, &PPC::VSRCRegClass);
17839 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17840 return std::make_pair(0U, &PPC::VSSRCRegClass);
17841 return std::make_pair(0U, &PPC::VSFRCRegClass);
17842 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
17843 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17844 return std::make_pair(0U, &PPC::VSSRCRegClass);
17846 return std::make_pair(0U, &PPC::VSFRCRegClass);
17847 }
else if (Constraint ==
"lr") {
17848 if (VT == MVT::i64)
17849 return std::make_pair(0U, &PPC::LR8RCRegClass);
17851 return std::make_pair(0U, &PPC::LRRCRegClass);
17856 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
17860 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
17861 int VSNum = atoi(Constraint.
data() + 3);
17862 assert(VSNum >= 0 && VSNum <= 63 &&
17863 "Attempted to access a vsr out of range");
17865 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
17866 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
17871 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
17872 int RegNum = atoi(Constraint.
data() + 2);
17873 if (RegNum > 31 || RegNum < 0)
17875 if (VT == MVT::f32 || VT == MVT::i32)
17876 return Subtarget.hasSPE()
17877 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
17878 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
17879 if (VT == MVT::f64 || VT == MVT::i64)
17880 return Subtarget.hasSPE()
17881 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
17882 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
17886 std::pair<unsigned, const TargetRegisterClass *> R =
17895 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
17896 PPC::GPRCRegClass.contains(R.first))
17897 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
17898 PPC::sub_32, &PPC::G8RCRegClass),
17899 &PPC::G8RCRegClass);
17902 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
17903 R.first = PPC::CR0;
17904 R.second = &PPC::CRRCRegClass;
17908 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
17909 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
17910 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
17911 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
17912 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
17913 "default AIX AltiVec ABI and cannot be used\n";
17923 std::vector<SDValue> &
Ops,
17928 if (Constraint.
size() > 1)
17931 char Letter = Constraint[0];
17946 EVT TCVT = MVT::i64;
17987 if (Result.getNode()) {
17988 Ops.push_back(Result);
17999 if (
I.getNumOperands() <= 1)
18003 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18004 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18005 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18008 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18024 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18036 switch (AM.
Scale) {
18064 unsigned Depth =
Op.getConstantOperandVal(0);
18088 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18096 unsigned Depth =
Op.getConstantOperandVal(0);
18103 bool isPPC64 = PtrVT == MVT::i64;
18109 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18111 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18117 FrameAddr, MachinePointerInfo());
18121#define GET_REGISTER_MATCHER
18122#include "PPCGenAsmMatcher.inc"
18126 bool IsPPC64 = Subtarget.isPPC64();
18138 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18144 Reg = Reg.id() - PPC::R0 + PPC::X0;
18151 if (Subtarget.is32BitELFABI())
18156 if (Subtarget.isAIXABI())
18170 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18186 case Intrinsic::ppc_atomicrmw_xchg_i128:
18187 case Intrinsic::ppc_atomicrmw_add_i128:
18188 case Intrinsic::ppc_atomicrmw_sub_i128:
18189 case Intrinsic::ppc_atomicrmw_nand_i128:
18190 case Intrinsic::ppc_atomicrmw_and_i128:
18191 case Intrinsic::ppc_atomicrmw_or_i128:
18192 case Intrinsic::ppc_atomicrmw_xor_i128:
18193 case Intrinsic::ppc_cmpxchg_i128:
18195 Info.memVT = MVT::i128;
18196 Info.ptrVal =
I.getArgOperand(0);
18198 Info.align =
Align(16);
18202 case Intrinsic::ppc_atomic_load_i128:
18204 Info.memVT = MVT::i128;
18205 Info.ptrVal =
I.getArgOperand(0);
18207 Info.align =
Align(16);
18210 case Intrinsic::ppc_atomic_store_i128:
18212 Info.memVT = MVT::i128;
18213 Info.ptrVal =
I.getArgOperand(2);
18215 Info.align =
Align(16);
18218 case Intrinsic::ppc_altivec_lvx:
18219 case Intrinsic::ppc_altivec_lvxl:
18220 case Intrinsic::ppc_altivec_lvebx:
18221 case Intrinsic::ppc_altivec_lvehx:
18222 case Intrinsic::ppc_altivec_lvewx:
18223 case Intrinsic::ppc_vsx_lxvd2x:
18224 case Intrinsic::ppc_vsx_lxvw4x:
18225 case Intrinsic::ppc_vsx_lxvd2x_be:
18226 case Intrinsic::ppc_vsx_lxvw4x_be:
18227 case Intrinsic::ppc_vsx_lxvl:
18228 case Intrinsic::ppc_vsx_lxvll: {
18231 case Intrinsic::ppc_altivec_lvebx:
18234 case Intrinsic::ppc_altivec_lvehx:
18237 case Intrinsic::ppc_altivec_lvewx:
18240 case Intrinsic::ppc_vsx_lxvd2x:
18241 case Intrinsic::ppc_vsx_lxvd2x_be:
18251 Info.ptrVal =
I.getArgOperand(0);
18254 Info.align =
Align(1);
18258 case Intrinsic::ppc_altivec_stvx:
18259 case Intrinsic::ppc_altivec_stvxl:
18260 case Intrinsic::ppc_altivec_stvebx:
18261 case Intrinsic::ppc_altivec_stvehx:
18262 case Intrinsic::ppc_altivec_stvewx:
18263 case Intrinsic::ppc_vsx_stxvd2x:
18264 case Intrinsic::ppc_vsx_stxvw4x:
18265 case Intrinsic::ppc_vsx_stxvd2x_be:
18266 case Intrinsic::ppc_vsx_stxvw4x_be:
18267 case Intrinsic::ppc_vsx_stxvl:
18268 case Intrinsic::ppc_vsx_stxvll: {
18271 case Intrinsic::ppc_altivec_stvebx:
18274 case Intrinsic::ppc_altivec_stvehx:
18277 case Intrinsic::ppc_altivec_stvewx:
18280 case Intrinsic::ppc_vsx_stxvd2x:
18281 case Intrinsic::ppc_vsx_stxvd2x_be:
18291 Info.ptrVal =
I.getArgOperand(1);
18294 Info.align =
Align(1);
18298 case Intrinsic::ppc_stdcx:
18299 case Intrinsic::ppc_stwcx:
18300 case Intrinsic::ppc_sthcx:
18301 case Intrinsic::ppc_stbcx: {
18303 auto Alignment =
Align(8);
18305 case Intrinsic::ppc_stdcx:
18308 case Intrinsic::ppc_stwcx:
18310 Alignment =
Align(4);
18312 case Intrinsic::ppc_sthcx:
18314 Alignment =
Align(2);
18316 case Intrinsic::ppc_stbcx:
18318 Alignment =
Align(1);
18323 Info.ptrVal =
I.getArgOperand(0);
18325 Info.align = Alignment;
18340 const AttributeList &FuncAttributes)
const {
18344 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
18345 if (
Op.isMemset() && Subtarget.hasVSX()) {
18350 if (TailSize > 2 && TailSize <= 4) {
18355 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
18360 if (Subtarget.isPPC64()) {
18371 assert(Ty->isIntegerTy());
18373 unsigned BitSize = Ty->getPrimitiveSizeInBits();
18374 return !(BitSize == 0 || BitSize > 64);
18382 return NumBits1 == 64 && NumBits2 == 32;
18390 return NumBits1 == 64 && NumBits2 == 32;
18397 EVT MemVT = LD->getMemoryVT();
18398 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
18399 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
18415 "invalid fpext types");
18417 if (DestVT == MVT::f128)
18432 unsigned *
Fast)
const {
18446 !Subtarget.allowsUnalignedFPAccess())
18450 if (Subtarget.hasVSX()) {
18451 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
18452 VT != MVT::v4f32 && VT != MVT::v4i32)
18459 if (VT == MVT::ppcf128)
18474 if (!ConstNode->getAPIntValue().isSignedIntN(64))
18482 int64_t Imm = ConstNode->getSExtValue();
18503 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
18505 switch (Ty->getScalarType()->getTypeID()) {
18510 return Subtarget.hasP9Vector();
18518 if (!
I->hasOneUse())
18522 assert(
User &&
"A single use instruction with no uses.");
18524 switch (
I->getOpcode()) {
18525 case Instruction::FMul: {
18527 if (
User->getOpcode() != Instruction::FSub &&
18528 User->getOpcode() != Instruction::FAdd)
18541 case Instruction::Load: {
18554 if (
User->getOpcode() != Instruction::Store)
18574 static const MCPhysReg ScratchRegs[] = {
18575 PPC::X12, PPC::LR8, PPC::CTR8, 0
18578 return ScratchRegs;
18582 const Constant *PersonalityFn)
const {
18583 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
18587 const Constant *PersonalityFn)
const {
18588 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
18593 EVT VT ,
unsigned DefinedValues)
const {
18594 if (VT == MVT::v2i64)
18595 return Subtarget.hasDirectMove();
18597 if (Subtarget.hasVSX())
18631 bool LegalOps,
bool OptForSize,
18633 unsigned Depth)
const {
18637 unsigned Opc =
Op.getOpcode();
18638 EVT VT =
Op.getValueType();
18663 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
18667 N0Cost,
Depth + 1);
18671 N1Cost,
Depth + 1);
18673 if (NegN0 && N0Cost <= N1Cost) {
18674 Cost = std::min(N0Cost, N2Cost);
18676 }
else if (NegN1) {
18677 Cost = std::min(N1Cost, N2Cost);
18697 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
18703 bool ForCodeSize)
const {
18704 if (!VT.
isSimple() || !Subtarget.hasVSX())
18714 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
18719 APSInt IntResult(16,
false);
18724 if (IsExact && IntResult <= 15 && IntResult >= -16)
18726 return Imm.isZero();
18729 return Imm.isPosZero();
18741 unsigned Opcode =
N->getOpcode();
18761 if (Mask->getZExtValue() == OpSizeInBits - 1)
18768 DAGCombinerInfo &DCI)
const {
18769 EVT VT =
N->getValueType(0);
18772 unsigned Opc =
N->getOpcode();
18774 "Unexpected opcode.");
18781 if (EltTy != MVT::i64 && EltTy != MVT::i32)
18785 uint64_t SplatBits = 0;
18786 bool AddSplatCase =
false;
18790 AddSplatCase =
true;
18794 if (!AddSplatCase) {
18798 unsigned SplatBitSize;
18800 APInt APSplatBits, APSplatUndef;
18802 bool BVNIsConstantSplat =
18804 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
18805 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
18816 if (SplatBits == (EltBits - 1)) {
18830 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
18838 if (EltTy != MVT::i64 || SplatBits != 1)
18841 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
18844SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18848 if (
N->getValueType(0).isVector())
18849 return combineVectorShift(
N, DCI);
18853 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
18856 N->getValueType(0) != MVT::i64)
18871 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
18877SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18881 if (
N->getValueType(0).isVector())
18882 return combineVectorShift(
N, DCI);
18887SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18891 if (
N->getValueType(0).isVector())
18892 return combineVectorShift(
N, DCI);
18903 if (!Subtarget.isPPC64())
18909 auto isZextOfCompareWithConstant = [](
SDValue Op) {
18911 Op.getValueType() != MVT::i64)
18915 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
18916 Cmp.getOperand(0).getValueType() != MVT::i64)
18920 int64_t NegConstant = 0 -
Constant->getSExtValue();
18929 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
18930 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
18933 if (LHSHasPattern && !RHSHasPattern)
18935 else if (!LHSHasPattern && !RHSHasPattern)
18939 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18942 SDValue Z = Cmp.getOperand(0);
18944 int64_t NegConstant = 0 -
Constant->getSExtValue();
18957 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18975 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19016 if (!GSDN || !ConstNode)
19036SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19056 DAGCombinerInfo &DCI)
const {
19058 if (Subtarget.useCRBits()) {
19060 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19061 return CRTruncValue;
19068 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19071 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19081 EltToExtract = EltToExtract ? 0 : 1;
19091 return DCI.DAG.getNode(
19093 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19098SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19099 SelectionDAG &DAG = DCI.DAG;
19102 if (!ConstOpOrElement)
19110 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19111 switch (this->Subtarget.getCPUDirective()) {
19134 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19138 EVT VT =
N->getValueType(0);
19143 APInt MulAmtAbs = MulAmt.
abs();
19145 if ((MulAmtAbs - 1).isPowerOf2()) {
19149 if (!IsProfitable(IsNeg,
true, VT))
19162 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19166 if (!IsProfitable(IsNeg,
false, VT))
19187 DAGCombinerInfo &DCI)
const {
19191 SDNodeFlags
Flags =
N->getFlags();
19192 EVT VT =
N->getValueType(0);
19193 SelectionDAG &DAG = DCI.DAG;
19195 unsigned Opc =
N->getOpcode();
19197 bool LegalOps = !DCI.isBeforeLegalizeOps();
19205 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
19221bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19223 if (!Subtarget.is64BitELFABI())
19233 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19238 if (!Callee ||
Callee->isVarArg())
19251bool PPCTargetLowering::
19252isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19257 if (CI->getBitWidth() > 64)
19259 int64_t ConstVal = CI->getZExtValue();
19261 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19270PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19276 if ((Flags & FlagSet) == FlagSet)
19279 if ((Flags & FlagSet) == FlagSet)
19282 if ((Flags & FlagSet) == FlagSet)
19285 if ((Flags & FlagSet) == FlagSet)
19306 if ((FrameIndexAlign % 4) != 0)
19307 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
19308 if ((FrameIndexAlign % 16) != 0)
19309 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
19313 if ((FrameIndexAlign % 4) == 0)
19315 if ((FrameIndexAlign % 16) == 0)
19328 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
19329 if ((Imm & 0x3) == 0)
19331 if ((Imm & 0xf) == 0)
19337 const APInt &ConstImm = CN->getAPIntValue();
19356 const APInt &ConstImm = CN->getAPIntValue();
19366 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
19386unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
19391 if (!Subtarget.hasP9Vector())
19396 if (Subtarget.hasPrefixInstrs())
19399 if (Subtarget.hasSPE())
19408 unsigned ParentOp = Parent->
getOpcode();
19412 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
19413 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
19425 if (LSB->isIndexed())
19431 assert(MN &&
"Parent should be a MemSDNode!");
19436 "Not expecting scalar integers larger than 16 bytes!");
19439 else if (
Size == 32)
19446 else if (
Size == 256) {
19447 assert(Subtarget.pairedVectorMemops() &&
19448 "256-bit vectors are only available when paired vector memops is "
19456 else if (MemVT == MVT::f128 || MemVT.
isVector())
19487 FlagSet &= ~PPC::MOF_NoExt;
19492 bool IsNonP1034BitConst =
19496 IsNonP1034BitConst)
19509 int16_t ForceXFormImm = 0;
19512 Disp =
N.getOperand(0);
19513 Base =
N.getOperand(1);
19524 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
19525 Disp =
N.getOperand(0);
19526 Base =
N.getOperand(1);
19531 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
19540 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
19546 if (PartVT == MVT::f64 &&
19547 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
19549 Val = DAG.
getNode(ISD::BITCAST,
DL, MVT::f64, Val);
19556SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
19560 EVT RetVT =
Op.getValueType();
19567 EVT ArgVT =
N.getValueType();
19571 Entry.IsZExt = !Entry.IsSExt;
19572 Args.push_back(Entry);
19580 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
19593SDValue PPCTargetLowering::lowerLibCallBasedOnType(
19594 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
19596 if (
Op.getValueType() == MVT::f32)
19597 return lowerToLibCall(LibCallFloatName,
Op, DAG);
19599 if (
Op.getValueType() == MVT::f64)
19600 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
19605bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
19606 SDNodeFlags
Flags =
Op.getNode()->getFlags();
19607 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
19611bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
19612 return Op.getNode()->getFlags().hasApproximateFuncs();
19615bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
19619SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
19620 const char *LibCallFloatName,
19621 const char *LibCallDoubleNameFinite,
19622 const char *LibCallFloatNameFinite,
19625 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
19628 if (!isLowringToMASSFiniteSafe(
Op))
19629 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
19632 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
19633 LibCallDoubleNameFinite,
Op, DAG);
19637 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
19638 "__xl_powf_finite",
Op, DAG);
19642 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
19643 "__xl_sinf_finite",
Op, DAG);
19647 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
19648 "__xl_cosf_finite",
Op, DAG);
19652 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
19653 "__xl_logf_finite",
Op, DAG);
19657 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
19658 "__xl_log10f_finite",
Op, DAG);
19662 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
19663 "__xl_expf_finite",
Op, DAG);
19688 unsigned Flags = computeMOFlags(Parent,
N, DAG);
19699 assert(Subtarget.isUsingPCRelativeCalls() &&
19700 "Must be using PC-Relative calls when a valid PC-Relative node is "
19730 Disp =
N.getOperand(1).getOperand(0);
19735 Base =
N.getOperand(0);
19743 EVT CNType = CN->getValueType(0);
19744 uint64_t CNImm = CN->getZExtValue();
19755 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
19757 int32_t Addr = (int32_t)CNImm;
19762 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
19778 unsigned Opcode =
N.getOpcode();
19786 Base =
N.getOperand(0);
19805 Base = FI ?
N :
N.getOperand(1);
19806 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
19817 bool IsVarArg)
const {
19827 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
19863 return Intrinsic::ppc_atomicrmw_xchg_i128;
19865 return Intrinsic::ppc_atomicrmw_add_i128;
19867 return Intrinsic::ppc_atomicrmw_sub_i128;
19869 return Intrinsic::ppc_atomicrmw_and_i128;
19871 return Intrinsic::ppc_atomicrmw_or_i128;
19873 return Intrinsic::ppc_atomicrmw_xor_i128;
19875 return Intrinsic::ppc_atomicrmw_nand_i128;
19883 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
19885 assert(ValTy->getPrimitiveSizeInBits() == 128);
19887 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
19889 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
19890 Value *LoHi = Builder.CreateIntrinsic(
19892 {AlignedAddr, IncrLo, IncrHi});
19893 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
19894 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
19895 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
19896 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
19897 return Builder.CreateOr(
19898 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19905 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
19907 assert(ValTy->getPrimitiveSizeInBits() == 128);
19911 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
19913 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
19914 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
19916 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
19919 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
19921 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
19922 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
19923 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
19924 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
19925 return Builder.CreateOr(
19926 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19930 return Subtarget.useCRBits();
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
static SDValue GeneratePerfectShuffle(unsigned ID, SDValue V1, SDValue V2, unsigned PFEntry, SDValue LHS, SDValue RHS, SelectionDAG &DAG, const SDLoc &DL)
GeneratePerfectShuffle - Given an entry in the perfect-shuffle table, emit the specified operations t...
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
static std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static bool isLoad(int Opcode)
static bool isFloatingPointZero(SDValue Op)
isFloatingPointZero - Return true if this is +0.0.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
Atomic ordering constants.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isConstantOrUndef(const SDValue Op)
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 bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool 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 SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static 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 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)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
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 ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static 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...
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableP10StoreForward("disable-p10-store-forward", cl::desc("disable P10 store forward-friendly conversion"), cl::Hidden, cl::init(false))
static bool isXXBRShuffleMaskHelper(ShuffleVectorSDNode *N, int Width)
static bool isFunctionGlobalAddress(const GlobalValue *CalleeGV)
static bool isSplatBV(SDValue Op)
static SDValue combineBVOfVecSExt(SDNode *N, SelectionDAG &DAG)
static cl::opt< bool > DisableILPPref("disable-ppc-ilp-pref", cl::desc("disable setting the node scheduling preference to ILP on PPC"), cl::Hidden)
static bool isNByteElemShuffleMask(ShuffleVectorSDNode *, unsigned, int)
Check that the mask is shuffling N byte elements.
static SDValue combineBVOfConsecutiveLoads(SDNode *N, SelectionDAG &DAG)
Reduce the number of loads when building a vector.
static bool isValidPCRelNode(SDValue N)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
pre isel intrinsic Pre ISel Intrinsic Lowering
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG, const SparcSubtarget *Subtarget)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
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.
@ USubCond
Subtract only if no unsigned overflow.
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ UIncWrap
Increment one up to a maximum value.
@ UDecWrap
Decrement one until a minimum value or zero.
BinOp getOperation() const
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool isStrictFP() const
Determine if the call requires strict floating point semantics.
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
LLVM_ABI bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
LLVM_ABI StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
LLVM_ABI bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
@ INVALID_SIMPLE_VALUE_TYPE
uint64_t getScalarSizeInBits() const
unsigned getVectorNumElements() const
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
static auto fixedlen_vector_valuetypes()
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isScalarInteger() const
Return true if this is an integer, not including vectors.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
static MVT getIntegerVT(unsigned BitWidth)
static auto fp_valuetypes()
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
const PPCRegisterInfo * getRegisterInfo() const override
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
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...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
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.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
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.
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
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
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
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...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue 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...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
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).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
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.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
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.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
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.
TargetLowering(const TargetLowering &)=delete
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual bool useLoadStackGuardNode(const Module &M) const
If this function returns true, SelectionDAGBuilder emits a LOAD_STACK_GUARD node when it is lowering ...
virtual unsigned combineRepeatedFPDivisors() const
Indicate whether this target prefers to combine FDIVs with the same divisor.
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual 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.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
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...
@ 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.
@ ADD
Simple integer binary arithmetic operators.
@ 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.
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ 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...
@ SSUBO
Same for subtraction.
@ FCANONICALIZE
Returns platform specific canonical encoding of a floating point number.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ 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.
@ 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) ...
@ 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.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ UADDO_CARRY
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ 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.
@ 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.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ 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)...
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_PIC_LO_FLAG
MO_PIC_LO_FLAG = MO_PIC_FLAG | MO_LO.
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_GOT_PCREL_FLAG
MO_GOT_PCREL_FLAG = MO_PCREL_FLAG | MO_GOT_FLAG.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_PCREL_FLAG
MO_PCREL_FLAG - If this bit is set, the symbol reference is relative to the current instruction addre...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TLS_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TLS.
@ MO_PLT
On PPC, the 12 bits are not enough for all target operand flags.
@ MO_TLS
Symbol for VK_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ 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.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ 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...
@ 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 ....
@ SETBC
SETBC - The ISA 3.1 (P10) SETBC instruction.
@ 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 ...
@ SETBCR
SETBCR - The ISA 3.1 (P10) SETBCR 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.
@ VSRQ
VSRQ - The ISA 3.1 (P10) Vector Shift right quadword instruction.
@ 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.
@ ADDC
These nodes represent PPC arithmetic operations with carry.
@ 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...
@ 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...
@ 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.
Define some predicates that are used for node matching.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
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.
@ Define
Register definition.
Invariant opcodes: All instruction sets have these as their low opcodes.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
LLVM_ABI void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
bool isa_and_nonnull(const Y &Val)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
auto dyn_cast_or_null(const Y &Val)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
To bit_cast(const From &from) noexcept
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI 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.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
void setNoFPExcept(bool b)
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setTailCall(bool Value=true)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
CallLoweringInfo & setChain(SDValue InChain)
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)
This structure is used to pass arguments to makeLibCall function.