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(
"Set minimum of largest number of comparisons to use bit test for "
148 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
152 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
153 "function to use initial-exec"));
158 "Number of shuffles lowered to a VPERM or XXPERM");
159STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
180 initializeAddrModeMap();
183 bool isPPC64 = Subtarget.isPPC64();
185 const MVT RegVT = Subtarget.getScalarIntVT();
193 if (!Subtarget.hasEFPU2())
210 if (!Subtarget.hasP10Vector()) {
236 if (Subtarget.isISA3_0()) {
269 if (!Subtarget.hasSPE()) {
276 if (Subtarget.useCRBits()) {
279 if (isPPC64 || Subtarget.hasFPCVT()) {
345 if (Subtarget.isISA3_0()) {
380 if (!Subtarget.hasSPE()) {
385 if (Subtarget.hasVSX()) {
390 if (Subtarget.hasFSQRT()) {
395 if (Subtarget.hasFPRND()) {
436 if (Subtarget.hasSPE()) {
446 if (Subtarget.hasSPE())
450 if (!Subtarget.hasFSQRT() && !(Subtarget.hasFRSQRTE() && Subtarget.hasFRE()))
453 if (!Subtarget.hasFSQRT() &&
454 !(Subtarget.hasFRSQRTES() && Subtarget.hasFRES()))
457 if (Subtarget.hasFCPSGN()) {
465 if (Subtarget.hasFPRND()) {
479 if (Subtarget.isISA3_1()) {
485 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
489 if (Subtarget.isISA3_0()) {
509 if (!Subtarget.useCRBits()) {
522 if (!Subtarget.useCRBits())
525 if (Subtarget.hasFPU()) {
536 if (!Subtarget.useCRBits())
541 if (Subtarget.hasSPE()) {
565 if (Subtarget.hasDirectMove() && isPPC64) {
625 if (Subtarget.is64BitELFABI()) {
636 }
else if (Subtarget.is32BitELFABI()) {
644 if (Subtarget.is32BitELFABI())
660 if (Subtarget.isISA3_0() && isPPC64) {
687 if (Subtarget.hasSPE()) {
709 if (Subtarget.has64BitSupport()) {
724 if (Subtarget.hasLFIWAX() || isPPC64) {
730 if (Subtarget.hasSPE()) {
740 if (Subtarget.hasFPCVT()) {
741 if (Subtarget.has64BitSupport()) {
762 if (Subtarget.use64BitRegs()) {
780 if (Subtarget.has64BitSupport()) {
787 if (Subtarget.hasVSX()) {
796 if (Subtarget.hasAltivec()) {
797 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
812 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
825 if (Subtarget.hasVSX()) {
831 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
841 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
915 if (!Subtarget.hasP8Vector()) {
957 if (Subtarget.hasAltivec())
958 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
961 if (Subtarget.hasP8Altivec())
972 if (Subtarget.hasVSX()) {
978 if (Subtarget.hasP8Altivec())
983 if (Subtarget.isISA3_1()) {
1029 if (Subtarget.hasVSX()) {
1032 if (Subtarget.hasP8Vector()) {
1036 if (Subtarget.hasDirectMove() && isPPC64) {
1085 if (Subtarget.hasP8Vector())
1094 if (Subtarget.hasP8Altivec()) {
1121 if (Subtarget.isISA3_1())
1224 if (Subtarget.hasP8Altivec()) {
1229 if (Subtarget.hasP9Vector()) {
1234 if (Subtarget.useCRBits()) {
1294 }
else if (Subtarget.hasVSX()) {
1319 for (
MVT VT : {MVT::f32, MVT::f64}) {
1338 if (Subtarget.hasP9Altivec()) {
1339 if (Subtarget.isISA3_1()) {
1362 if (Subtarget.hasP10Vector()) {
1367 if (Subtarget.pairedVectorMemops()) {
1372 if (Subtarget.hasMMA()) {
1373 if (Subtarget.isISAFuture()) {
1389 if (Subtarget.has64BitSupport())
1392 if (Subtarget.isISA3_1())
1410 if (Subtarget.hasAltivec()) {
1427 if (Subtarget.hasFPCVT())
1430 if (Subtarget.useCRBits())
1439 if (Subtarget.useCRBits()) {
1445 if (Subtarget.useCRBits()) {
1461 auto CPUDirective = Subtarget.getCPUDirective();
1462 switch (CPUDirective) {
1485 if (Subtarget.enableMachineScheduler())
1559void PPCTargetLowering::initializeAddrModeMap() {
1610 if (MaxAlign == MaxMaxAlign)
1613 if (MaxMaxAlign >= 32 &&
1614 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1615 MaxAlign =
Align(32);
1616 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1618 MaxAlign =
Align(16);
1622 if (EltAlign > MaxAlign)
1623 MaxAlign = EltAlign;
1625 for (
auto *EltTy : STy->elements()) {
1628 if (EltAlign > MaxAlign)
1629 MaxAlign = EltAlign;
1630 if (MaxAlign == MaxMaxAlign)
1643 if (Subtarget.hasAltivec())
1649 return Subtarget.useSoftFloat();
1653 return Subtarget.hasSPE();
1661 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1662 if (!Subtarget.isPPC64() || !Subtarget.hasVSX())
1666 if (VTy->getScalarType()->isIntegerTy()) {
1668 if (ElemSizeInBits == 32) {
1669 Index = Subtarget.isLittleEndian() ? 2 : 1;
1672 if (ElemSizeInBits == 64) {
1673 Index = Subtarget.isLittleEndian() ? 1 : 0;
1698 return "PPCISD::FTSQRT";
1700 return "PPCISD::FSQRT";
1705 return "PPCISD::XXSPLTI_SP_TO_DP";
1707 return "PPCISD::XXSPLTI32DX";
1711 return "PPCISD::XXPERM";
1714 return "PPCISD::VSRQ";
1733 return "PPCISD::CALL_RM";
1735 return "PPCISD::CALL_NOP_RM";
1737 return "PPCISD::CALL_NOTOC_RM";
1742 return "PPCISD::BCTRL_RM";
1744 return "PPCISD::BCTRL_LOAD_TOC_RM";
1756 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1758 return "PPCISD::ANDI_rec_1_EQ_BIT";
1760 return "PPCISD::ANDI_rec_1_GT_BIT";
1775 return "PPCISD::ST_VSR_SCAL_INT";
1804 return "PPCISD::PADDI_DTPREL";
1806 return "PPCISD::VADD_SPLAT";
1817 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1819 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1829 return "PPCISD::STRICT_FADDRTZ";
1831 return "PPCISD::STRICT_FCTIDZ";
1833 return "PPCISD::STRICT_FCTIWZ";
1835 return "PPCISD::STRICT_FCTIDUZ";
1837 return "PPCISD::STRICT_FCTIWUZ";
1839 return "PPCISD::STRICT_FCFID";
1841 return "PPCISD::STRICT_FCFIDU";
1843 return "PPCISD::STRICT_FCFIDS";
1845 return "PPCISD::STRICT_FCFIDUS";
1848 return "PPCISD::STORE_COND";
1850 return "PPCISD::SETBC";
1852 return "PPCISD::SETBCR";
1854 return "PPCISD::ADDC";
1856 return "PPCISD::ADDE";
1858 return "PPCISD::SUBC";
1860 return "PPCISD::SUBE";
1868 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1885 return CFP->getValueAPF().isZero();
1890 return CFP->getValueAPF().isZero();
1898 return Op < 0 ||
Op == Val;
1910 if (ShuffleKind == 0) {
1913 for (
unsigned i = 0; i != 16; ++i)
1916 }
else if (ShuffleKind == 2) {
1919 for (
unsigned i = 0; i != 16; ++i)
1922 }
else if (ShuffleKind == 1) {
1923 unsigned j = IsLE ? 0 : 1;
1924 for (
unsigned i = 0; i != 8; ++i)
1941 if (ShuffleKind == 0) {
1944 for (
unsigned i = 0; i != 16; i += 2)
1948 }
else if (ShuffleKind == 2) {
1951 for (
unsigned i = 0; i != 16; i += 2)
1955 }
else if (ShuffleKind == 1) {
1956 unsigned j = IsLE ? 0 : 2;
1957 for (
unsigned i = 0; i != 8; i += 2)
1978 if (!Subtarget.hasP8Vector())
1982 if (ShuffleKind == 0) {
1985 for (
unsigned i = 0; i != 16; i += 4)
1991 }
else if (ShuffleKind == 2) {
1994 for (
unsigned i = 0; i != 16; i += 4)
2000 }
else if (ShuffleKind == 1) {
2001 unsigned j = IsLE ? 0 : 4;
2002 for (
unsigned i = 0; i != 8; i += 4)
2019 unsigned LHSStart,
unsigned RHSStart) {
2020 if (
N->getValueType(0) != MVT::v16i8)
2022 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2023 "Unsupported merge size!");
2025 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2026 for (
unsigned j = 0; j != UnitSize; ++j) {
2028 LHSStart+j+i*UnitSize) ||
2030 RHSStart+j+i*UnitSize))
2045 if (ShuffleKind == 1)
2047 else if (ShuffleKind == 2)
2052 if (ShuffleKind == 1)
2054 else if (ShuffleKind == 0)
2070 if (ShuffleKind == 1)
2072 else if (ShuffleKind == 2)
2077 if (ShuffleKind == 1)
2079 else if (ShuffleKind == 0)
2129 unsigned RHSStartValue) {
2130 if (
N->getValueType(0) != MVT::v16i8)
2133 for (
unsigned i = 0; i < 2; ++i)
2134 for (
unsigned j = 0; j < 4; ++j)
2136 i*RHSStartValue+j+IndexOffset) ||
2138 i*RHSStartValue+j+IndexOffset+8))
2160 unsigned indexOffset = CheckEven ? 4 : 0;
2161 if (ShuffleKind == 1)
2163 else if (ShuffleKind == 2)
2169 unsigned indexOffset = CheckEven ? 0 : 4;
2170 if (ShuffleKind == 1)
2172 else if (ShuffleKind == 0)
2188 if (
N->getValueType(0) != MVT::v16i8)
2195 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2198 if (i == 16)
return -1;
2203 if (ShiftAmt < i)
return -1;
2208 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2210 for (++i; i != 16; ++i)
2213 }
else if (ShuffleKind == 1) {
2215 for (++i; i != 16; ++i)
2222 ShiftAmt = 16 - ShiftAmt;
2231 EVT VT =
N->getValueType(0);
2232 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2233 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2236 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2240 if (
N->getMaskElt(0) % EltSize != 0)
2245 unsigned ElementBase =
N->getMaskElt(0);
2248 if (ElementBase >= 16)
2253 for (
unsigned i = 1; i != EltSize; ++i)
2254 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2257 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2259 if (
N->getMaskElt(i) < 0) {
2260 for (
unsigned j = 1; j != EltSize; ++j)
2261 if (
N->getMaskElt(i + j) >= 0)
2264 for (
unsigned j = 0; j != EltSize; ++j)
2265 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2282 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2283 "Unexpected element width.");
2284 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2286 unsigned NumOfElem = 16 / Width;
2287 unsigned MaskVal[16];
2288 for (
unsigned i = 0; i < NumOfElem; ++i) {
2289 MaskVal[0] =
N->getMaskElt(i * Width);
2290 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2292 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2296 for (
unsigned int j = 1; j < Width; ++j) {
2297 MaskVal[j] =
N->getMaskElt(i * Width + j);
2298 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2308 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2313 unsigned M0 =
N->getMaskElt(0) / 4;
2314 unsigned M1 =
N->getMaskElt(4) / 4;
2315 unsigned M2 =
N->getMaskElt(8) / 4;
2316 unsigned M3 =
N->getMaskElt(12) / 4;
2317 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2318 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2323 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2324 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2325 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2326 InsertAtByte = IsLE ? 12 : 0;
2331 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2332 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2333 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2334 InsertAtByte = IsLE ? 8 : 4;
2339 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2340 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2341 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2342 InsertAtByte = IsLE ? 4 : 8;
2347 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2348 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2349 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2350 InsertAtByte = IsLE ? 0 : 12;
2357 if (
N->getOperand(1).isUndef()) {
2360 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2361 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2362 InsertAtByte = IsLE ? 12 : 0;
2365 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2366 InsertAtByte = IsLE ? 8 : 4;
2369 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2370 InsertAtByte = IsLE ? 4 : 8;
2373 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2374 InsertAtByte = IsLE ? 0 : 12;
2383 bool &Swap,
bool IsLE) {
2384 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2390 unsigned M0 =
N->getMaskElt(0) / 4;
2391 unsigned M1 =
N->getMaskElt(4) / 4;
2392 unsigned M2 =
N->getMaskElt(8) / 4;
2393 unsigned M3 =
N->getMaskElt(12) / 4;
2397 if (
N->getOperand(1).isUndef()) {
2398 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2399 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2402 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2408 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2412 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2417 ShiftElts = (8 -
M0) % 8;
2418 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2423 ShiftElts = (4 -
M0) % 4;
2428 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2433 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2445 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2450 for (
int i = 0; i < 16; i += Width)
2451 if (
N->getMaskElt(i) != i + Width - 1)
2482 bool &Swap,
bool IsLE) {
2483 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2489 unsigned M0 =
N->getMaskElt(0) / 8;
2490 unsigned M1 =
N->getMaskElt(8) / 8;
2491 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2495 if (
N->getOperand(1).isUndef()) {
2496 if ((
M0 |
M1) < 2) {
2497 DM = IsLE ? (((
~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2505 if (
M0 > 1 &&
M1 < 2) {
2515 DM = (((
~M1) & 1) << 1) + ((~
M0) & 1);
2520 }
else if (
M0 > 1 &&
M1 < 2) {
2528 DM = (
M0 << 1) + (
M1 & 1);
2543 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2548 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2564 unsigned EltSize = 16/
N->getNumOperands();
2565 if (EltSize < ByteSize) {
2566 unsigned Multiple = ByteSize/EltSize;
2568 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2571 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2572 if (
N->getOperand(i).isUndef())
continue;
2576 if (!UniquedVals[i&(Multiple-1)].
getNode())
2577 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2578 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2588 bool LeadingZero =
true;
2589 bool LeadingOnes =
true;
2590 for (
unsigned i = 0; i != Multiple-1; ++i) {
2591 if (!UniquedVals[i].
getNode())
continue;
2598 if (!UniquedVals[Multiple-1].
getNode())
2605 if (!UniquedVals[Multiple-1].
getNode())
2616 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2617 if (
N->getOperand(i).isUndef())
continue;
2619 OpVal =
N->getOperand(i);
2620 else if (OpVal !=
N->getOperand(i))
2626 unsigned ValSizeInBytes = EltSize;
2629 Value = CN->getZExtValue();
2631 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2638 if (ValSizeInBytes < ByteSize)
return SDValue();
2649 if (MaskVal == 0)
return SDValue();
2669 Imm = (int16_t)
N->getAsZExtVal();
2670 if (
N->getValueType(0) == MVT::i32)
2671 return Imm == (int32_t)
N->getAsZExtVal();
2673 return Imm == (int64_t)
N->getAsZExtVal();
2691 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2699 for (
SDNode *U :
N->users()) {
2701 if (Memop->getMemoryVT() == MVT::f64) {
2702 Base =
N.getOperand(0);
2703 Index =
N.getOperand(1);
2746 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2751 Base =
N.getOperand(0);
2752 Index =
N.getOperand(1);
2754 }
else if (
N.getOpcode() ==
ISD::OR) {
2756 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2768 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2769 Base =
N.getOperand(0);
2770 Index =
N.getOperand(1);
2840 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2846 Base =
N.getOperand(0);
2849 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2851 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2852 "Cannot handle constant offsets yet!");
2853 Disp =
N.getOperand(1).getOperand(0);
2858 Base =
N.getOperand(0);
2861 }
else if (
N.getOpcode() ==
ISD::OR) {
2864 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2878 Base =
N.getOperand(0);
2891 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2894 CN->getValueType(0));
2899 if ((CN->getValueType(0) == MVT::i32 ||
2900 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2901 (!EncodingAlignment ||
2902 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2903 int Addr = (int)CN->getZExtValue();
2910 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2931 if (
N.getValueType() != MVT::i64)
2944 Base =
N.getOperand(0);
2960 Base =
N.getOperand(0);
2993 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2994 Base =
N.getOperand(0);
2995 Index =
N.getOperand(1);
3038 EVT MemVT = LD->getMemoryVT();
3045 if (!ST.hasP8Vector())
3050 if (!ST.hasP9Vector())
3062 if (
Use.getResNo() == 0 &&
3084 Ptr = LD->getBasePtr();
3085 VT = LD->getMemoryVT();
3086 Alignment = LD->getAlign();
3088 Ptr = ST->getBasePtr();
3089 VT = ST->getMemoryVT();
3090 Alignment = ST->getAlign();
3129 if (VT != MVT::i64) {
3134 if (Alignment <
Align(4))
3144 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3161 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3203 EVT VT = Subtarget.getScalarIntVT();
3205 : Subtarget.isAIXABI()
3217 EVT PtrVT =
Op.getValueType();
3223 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3224 if (Subtarget.isUsingPCRelativeCalls()) {
3233 return getTOCEntry(DAG, SDLoc(CP), GA);
3236 unsigned MOHiFlag, MOLoFlag;
3240 if (IsPIC && Subtarget.isSVR4ABI()) {
3243 return getTOCEntry(DAG, SDLoc(CP), GA);
3266 if (Subtarget.isPPC64() || Subtarget.isAIXABI())
3273 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3290 if (!Subtarget.isPPC64() || Subtarget.isAIXABI())
3303 EVT PtrVT =
Op.getValueType();
3321 return getTOCEntry(DAG,
SDLoc(JT), GA);
3324 unsigned MOHiFlag, MOLoFlag;
3328 if (IsPIC && Subtarget.isSVR4ABI()) {
3331 return getTOCEntry(DAG, SDLoc(GA), GA);
3341 EVT PtrVT =
Op.getValueType();
3346 if (Subtarget.isUsingPCRelativeCalls()) {
3357 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3360 return getTOCEntry(DAG, SDLoc(BASDN), GA);
3369 unsigned MOHiFlag, MOLoFlag;
3379 if (Subtarget.isAIXABI())
3380 return LowerGlobalTLSAddressAIX(
Op, DAG);
3382 return LowerGlobalTLSAddressLinux(
Op, DAG);
3404 if (
I.getOpcode() == Instruction::Call)
3406 if (
Function *CF = CI->getCalledFunction())
3407 if (CF->isDeclaration() &&
3408 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3416 unsigned TLSGVCnt = TLSGV.
size();
3426 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3439 const GlobalValue *GV = GA->
getGlobal();
3441 bool Is64Bit = Subtarget.isPPC64();
3445 if (Subtarget.hasAIXShLibTLSModelOpt())
3455 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3456 bool HasAIXSmallTLSGlobalAttr =
false;
3459 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3463 if (GVar->hasAttribute(
"aix-small-tls"))
3464 HasAIXSmallTLSGlobalAttr =
true;
3483 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3484 IsTLSLocalExecModel) {
3504 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3506 "currently only supported on AIX (64-bit mode).");
3512 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3516 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3518 "currently only supported on AIX (64-bit mode).");
3526 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3529 GlobalVariable *TLSGV =
3533 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3536 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3547 if (HasAIXSmallLocalDynamicTLS) {
3556 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3569 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3570 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3586 const GlobalValue *GV = GA->
getGlobal();
3588 bool is64bit = Subtarget.isPPC64();
3596 if (Subtarget.isUsingPCRelativeCalls()) {
3617 bool IsPCRel = Subtarget.isUsingPCRelativeCalls();
3626 MachinePointerInfo());
3635 if (!TM.isPositionIndependent())
3648 if (Subtarget.isUsingPCRelativeCalls()) {
3672 if (Subtarget.isUsingPCRelativeCalls()) {
3694 PtrVT, GOTPtr, TGA, TGA);
3696 PtrVT, TLSAddr, TGA);
3705 EVT PtrVT =
Op.getValueType();
3708 const GlobalValue *GV = GSDN->
getGlobal();
3712 if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
3713 if (Subtarget.isUsingPCRelativeCalls()) {
3720 MachinePointerInfo());
3730 return getTOCEntry(DAG,
DL, GA);
3733 unsigned MOHiFlag, MOLoFlag;
3737 if (IsPIC && Subtarget.isSVR4ABI()) {
3741 return getTOCEntry(DAG,
DL, GA);
3753 bool IsStrict =
Op->isStrictFPOpcode();
3759 EVT LHSVT =
LHS.getValueType();
3763 if (LHSVT == MVT::f128) {
3764 assert(!Subtarget.hasP9Vector() &&
3765 "SETCC for f128 is already legal under Power9!");
3776 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3778 if (
Op.getValueType() == MVT::v2i64) {
3781 if (
LHS.getValueType() == MVT::v2i64) {
3787 dl, MVT::v4i32, DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
LHS),
3788 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32,
RHS), CC);
3789 int ShuffV[] = {1, 0, 3, 2};
3794 dl, MVT::v4i32, Shuff, SetCC32));
3811 if (
C->isAllOnes() ||
C->isZero())
3821 EVT VT =
Op.getValueType();
3829 SDNode *
Node =
Op.getNode();
3830 EVT VT =
Node->getValueType(0);
3837 assert(!Subtarget.isPPC64() &&
"LowerVAARG is PPC32 only");
3841 VAListPtr, MachinePointerInfo(SV), MVT::i8);
3844 if (VT == MVT::i64) {
3863 FprPtr, MachinePointerInfo(SV), MVT::i8);
3874 DAG.
getLoad(MVT::i32, dl, InChain, OverflowAreaPtr, MachinePointerInfo());
3875 InChain = OverflowArea.
getValue(1);
3878 DAG.
getLoad(MVT::i32, dl, InChain, RegSaveAreaPtr, MachinePointerInfo());
3908 MachinePointerInfo(SV), MVT::i8);
3921 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3922 MachinePointerInfo(), MVT::i32);
3924 return DAG.
getLoad(VT, dl, InChain, Result, MachinePointerInfo());
3928 assert(!Subtarget.isPPC64() &&
"LowerVACOPY is PPC32 only");
3934 false,
true,
nullptr, std::nullopt,
3935 MachinePointerInfo(), MachinePointerInfo());
3940 return Op.getOperand(0);
3945 PPCFunctionInfo &MFI = *MF.
getInfo<PPCFunctionInfo>();
3947 assert((
Op.getOpcode() == ISD::INLINEASM ||
3948 Op.getOpcode() == ISD::INLINEASM_BR) &&
3949 "Expecting Inline ASM node.");
3959 if (
Op.getOperand(
NumOps - 1).getValueType() == MVT::Glue)
3964 const InlineAsm::Flag
Flags(
Op.getConstantOperandVal(i));
3965 unsigned NumVals =
Flags.getNumOperandRegisters();
3968 switch (
Flags.getKind()) {
3979 for (; NumVals; --NumVals, ++i) {
3981 if (
Reg != PPC::LR &&
Reg != PPC::LR8)
4004 if (Subtarget.isAIXABI()) {
4008 uint64_t
PointerSize = Subtarget.isPPC64() ? 8 : 4;
4009 MaybeAlign PointerAlign(PointerSize);
4010 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
4013 : MachineMemOperand::MONone;
4020 const Value *TrampolineAddr =
4030 DAG.
getLoad(PtrVT, dl, Chain, FPtr, MachinePointerInfo(Func, 0),
4031 PointerAlign, MMOFlags);
4033 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
4034 MachinePointerInfo(TrampolineAddr, 0));
4038 SDValue TOCFromDescriptorPtr =
4040 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
4041 MachinePointerInfo(Func, TOCPointerOffset),
4042 PointerAlign, MMOFlags);
4043 SDValue TrampolineTOCPointer =
4047 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
4048 MachinePointerInfo(TrampolineAddr, TOCPointerOffset));
4054 DAG.
getStore(Chain, dl, Nest, EnvPointer,
4055 MachinePointerInfo(TrampolineAddr, EnvPointerOffset));
4062 bool isPPC64 = (PtrVT == MVT::i64);
4066 Args.emplace_back(Trmp, IntPtrTy);
4069 DAG.
getConstant(isPPC64 ? 48 : 40, dl, Subtarget.getScalarIntVT()),
4071 Args.emplace_back(FPtr, IntPtrTy);
4072 Args.emplace_back(Nest, IntPtrTy);
4075 TargetLowering::CallLoweringInfo CLI(DAG);
4076 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4080 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4081 return CallResult.second;
4086 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4091 if (Subtarget.isPPC64() || Subtarget.isAIXABI()) {
4096 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4097 MachinePointerInfo(SV));
4131 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4134 uint64_t StackOffset = PtrVT.getSizeInBits()/8 - 1;
4137 uint64_t FPROffset = 1;
4145 MachinePointerInfo(SV), MVT::i8);
4146 uint64_t nextOffset = FPROffset;
4153 MachinePointerInfo(SV, nextOffset), MVT::i8);
4154 nextOffset += StackOffset;
4155 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4158 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4159 MachinePointerInfo(SV, nextOffset));
4160 nextOffset += FrameOffset;
4161 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4164 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4165 MachinePointerInfo(SV, nextOffset));
4170static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4171 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4172 PPC::F11, PPC::F12, PPC::F13};
4177 unsigned PtrByteSize) {
4179 if (Flags.isByVal())
4180 ArgSize = Flags.getByValSize();
4184 if (!Flags.isInConsecutiveRegs())
4185 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4194 unsigned PtrByteSize) {
4195 Align Alignment(PtrByteSize);
4198 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4199 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4200 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4201 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4202 Alignment =
Align(16);
4205 if (Flags.isByVal()) {
4206 auto BVAlign = Flags.getNonZeroByValAlign();
4207 if (BVAlign > PtrByteSize) {
4208 if (BVAlign.value() % PtrByteSize != 0)
4210 "ByVal alignment is not a multiple of the pointer size");
4212 Alignment = BVAlign;
4217 if (Flags.isInConsecutiveRegs()) {
4221 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4235 unsigned PtrByteSize,
unsigned LinkageSize,
4236 unsigned ParamAreaSize,
unsigned &ArgOffset,
4237 unsigned &AvailableFPRs,
4238 unsigned &AvailableVRs) {
4239 bool UseMemory =
false;
4244 ArgOffset =
alignTo(ArgOffset, Alignment);
4247 if (ArgOffset >= LinkageSize + ParamAreaSize)
4252 if (Flags.isInConsecutiveRegsLast())
4253 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4256 if (ArgOffset > LinkageSize + ParamAreaSize)
4261 if (!Flags.isByVal()) {
4262 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4263 if (AvailableFPRs > 0) {
4267 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4268 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4269 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4270 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4271 if (AvailableVRs > 0) {
4283 unsigned NumBytes) {
4287SDValue PPCTargetLowering::LowerFormalArguments(
4291 if (Subtarget.isAIXABI())
4292 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4294 if (Subtarget.is64BitELFABI())
4295 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4297 assert(Subtarget.is32BitELFABI());
4298 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4302SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4338 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4344 const Align PtrAlign(4);
4352 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4353 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4356 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4357 CCValAssign &VA = ArgLocs[i];
4361 const TargetRegisterClass *RC;
4369 RC = &PPC::GPRCRegClass;
4372 if (Subtarget.hasP8Vector())
4373 RC = &PPC::VSSRCRegClass;
4374 else if (Subtarget.hasSPE())
4375 RC = &PPC::GPRCRegClass;
4377 RC = &PPC::F4RCRegClass;
4380 if (Subtarget.hasVSX())
4381 RC = &PPC::VSFRCRegClass;
4382 else if (Subtarget.hasSPE())
4384 RC = &PPC::GPRCRegClass;
4386 RC = &PPC::F8RCRegClass;
4391 RC = &PPC::VRRCRegClass;
4394 RC = &PPC::VRRCRegClass;
4398 RC = &PPC::VRRCRegClass;
4405 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4406 assert(i + 1 < e &&
"No second half of double precision argument");
4411 if (!Subtarget.isLittleEndian())
4418 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4419 if (ValVT == MVT::i1)
4434 ArgOffset += ArgSize - ObjSize;
4452 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4457 unsigned MinReservedArea = CCByValInfo.getStackSize();
4458 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4474 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4475 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4477 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4480 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4483 unsigned NumFPArgRegs = std::size(FPArgRegs);
4492 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4493 NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8;
4496 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4509 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4524 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4528 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4541 if (!MemOps.
empty())
4552 const SDLoc &dl)
const {
4556 else if (
Flags.isZExt())
4563SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4569 bool isELFv2ABI = Subtarget.isELFv2ABI();
4570 bool isLittleEndian = Subtarget.isLittleEndian();
4573 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
4576 "fastcc not supported on varargs functions");
4582 unsigned PtrByteSize = 8;
4583 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
4586 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4587 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4590 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4591 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4594 const unsigned Num_GPR_Regs = std::size(GPR);
4596 const unsigned Num_VR_Regs = std::size(VR);
4604 bool HasParameterArea = !isELFv2ABI || isVarArg;
4605 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4606 unsigned NumBytes = LinkageSize;
4607 unsigned AvailableFPRs = Num_FPR_Regs;
4608 unsigned AvailableVRs = Num_VR_Regs;
4609 for (
const ISD::InputArg &In : Ins) {
4610 if (
In.Flags.isNest())
4614 LinkageSize, ParamAreaSize, NumBytes,
4615 AvailableFPRs, AvailableVRs))
4616 HasParameterArea =
true;
4623 unsigned ArgOffset = LinkageSize;
4624 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4627 unsigned CurArgIdx = 0;
4628 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4630 bool needsLoad =
false;
4631 EVT ObjectVT =
Ins[ArgNo].VT;
4632 EVT OrigVT =
Ins[ArgNo].ArgVT;
4634 unsigned ArgSize = ObjSize;
4635 ISD::ArgFlagsTy
Flags =
Ins[ArgNo].Flags;
4636 if (Ins[ArgNo].isOrigArg()) {
4637 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4638 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4643 unsigned CurArgOffset;
4645 auto ComputeArgOffset = [&]() {
4649 ArgOffset =
alignTo(ArgOffset, Alignment);
4650 CurArgOffset = ArgOffset;
4657 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4658 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4663 if (
Flags.isByVal()) {
4664 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4670 ObjSize =
Flags.getByValSize();
4671 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4693 if (HasParameterArea ||
4694 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4701 if (ObjSize < PtrByteSize) {
4705 if (!isLittleEndian) {
4711 if (GPR_idx != Num_GPR_Regs) {
4718 MachinePointerInfo(&*FuncArg), ObjType);
4723 ArgOffset += PtrByteSize;
4732 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4733 if (GPR_idx == Num_GPR_Regs)
4744 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4748 MachinePointerInfo(&*FuncArg, j), ObjType);
4752 ArgOffset += ArgSize;
4761 if (
Flags.isNest()) {
4766 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4767 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4775 if (GPR_idx != Num_GPR_Regs) {
4780 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4783 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4789 ArgSize = PtrByteSize;
4800 if (FPR_idx != Num_FPR_Regs) {
4803 if (ObjectVT == MVT::f32)
4805 Subtarget.hasP8Vector()
4806 ? &PPC::VSSRCRegClass
4807 : &PPC::F4RCRegClass);
4810 ? &PPC::VSFRCRegClass
4811 : &PPC::F8RCRegClass);
4826 if (ObjectVT == MVT::f32) {
4827 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4833 ArgVal = DAG.
getNode(ISD::BITCAST, dl, ObjectVT, ArgVal);
4845 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4846 ArgOffset += ArgSize;
4847 if (
Flags.isInConsecutiveRegsLast())
4848 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4862 if (VR_idx != Num_VR_Regs) {
4879 if (ObjSize < ArgSize && !isLittleEndian)
4880 CurArgOffset += ArgSize - ObjSize;
4883 ArgVal = DAG.
getLoad(ObjectVT, dl, Chain, FIN, MachinePointerInfo());
4890 unsigned MinReservedArea;
4891 if (HasParameterArea)
4892 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4894 MinReservedArea = LinkageSize;
4911 int Depth = ArgOffset;
4920 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4921 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4933 if (!MemOps.
empty())
4942 unsigned ParamSize) {
4944 if (!isTailCall)
return 0;
4948 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4950 if (SPDiff < FI->getTailCallSPDelta())
4966 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4979 if (!TM.shouldAssumeDSOLocal(CalleeGV))
5024 if (TM.getFunctionSections() || CalleeGV->
hasComdat() ||
5025 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
5028 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
5040 const unsigned PtrByteSize = 8;
5044 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
5045 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
5048 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
5049 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
5052 const unsigned NumGPRs = std::size(GPR);
5053 const unsigned NumFPRs = 13;
5054 const unsigned NumVRs = std::size(VR);
5055 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5057 unsigned NumBytes = LinkageSize;
5058 unsigned AvailableFPRs = NumFPRs;
5059 unsigned AvailableVRs = NumVRs;
5062 if (Param.Flags.isNest())
continue;
5065 LinkageSize, ParamAreaSize, NumBytes,
5066 AvailableFPRs, AvailableVRs))
5077 auto CalleeArgEnd = CB.
arg_end();
5080 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5081 const Value* CalleeArg = *CalleeArgIter;
5082 const Value* CallerArg = &(*CallerArgIter);
5083 if (CalleeArg == CallerArg)
5109 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5119bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5124 bool isCalleeExternalSymbol)
const {
5127 if (
DisableSCO && !TailCallOpt)
return false;
5130 if (isVarArg)
return false;
5137 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5173 if (!Subtarget.isUsingPCRelativeCalls() &&
5178 if (!Subtarget.isUsingPCRelativeCalls() &&
5206bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5219 if (
any_of(Ins, [](
const ISD::InputArg &IA) {
return IA.Flags.isByVal(); }))
5240 if (!
C)
return nullptr;
5242 int Addr =
C->getZExtValue();
5243 if ((Addr & 3) != 0 ||
5249 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5256struct TailCallArgumentInfo {
5261 TailCallArgumentInfo() =
default;
5271 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5272 SDValue Arg = TailCallArgs[i].Arg;
5273 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5274 int FI = TailCallArgs[i].FrameIdx;
5277 Chain, dl, Arg, FIN,
5286 int SPDiff,
const SDLoc &dl) {
5292 int SlotSize = Subtarget.isPPC64() ? 8 : 4;
5293 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5295 NewRetAddrLoc,
true);
5298 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5308 int SPDiff,
unsigned ArgOffset,
5310 int Offset = ArgOffset + SPDiff;
5313 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5315 TailCallArgumentInfo
Info;
5317 Info.FrameIdxOp = FIN;
5325SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5330 LROpOut = getReturnAddrFrameIndex(DAG);
5331 LROpOut = DAG.
getLoad(Subtarget.getScalarIntVT(), dl, Chain, LROpOut,
5332 MachinePointerInfo());
5349 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5357 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5381 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5391 if (!MemOpChains2.
empty())
5415SDValue PPCTargetLowering::LowerCallResult(
5423 CCRetInfo.AnalyzeCallResult(
5429 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5430 CCValAssign &VA = RVLocs[i];
5435 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5445 if (!Subtarget.isLittleEndian())
5513 bool IsStrictFPCall =
false) {
5517 unsigned RetOpc = 0;
5548 if (IsStrictFPCall) {
5579 auto isLocalCallee = [&]() {
5595 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5612 return getAIXFuncEntryPointSymbolSDNode(GV);
5619 const char *SymName = S->getSymbol();
5626 return getAIXFuncEntryPointSymbolSDNode(
F);
5632 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5640 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5647 assert(Callee.getNode() &&
"What no callee?");
5653 "Expected a CALLSEQ_STARTSDNode.");
5670 SDValue MTCTROps[] = {Chain, Callee, Glue};
5671 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5712 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5731 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5732 Alignment, MMOFlags);
5739 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5746 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5758 "Nest parameter is not supported on AIX.");
5774 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5777 const bool IsPPC64 = Subtarget.isPPC64();
5782 Ops.push_back(Chain);
5786 Ops.push_back(Callee);
5806 Ops.push_back(AddTOC);
5817 Ops.push_back(DAG.
getRegister(IsPPC64 ? PPC::CTR8 : PPC::CTR, RegVT));
5826 for (
const auto &[
Reg,
N] : RegsToPass)
5844 assert(Mask &&
"Missing call preserved mask for calling convention");
5849 Ops.push_back(Glue);
5852SDValue PPCTargetLowering::FinishCall(
5859 if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
5860 Subtarget.isAIXABI())
5867 if (!CFlags.IsIndirect)
5869 else if (Subtarget.usesFunctionDescriptors())
5871 dl, CFlags.HasNest, Subtarget);
5881 if (CFlags.IsTailCall) {
5889 (CFlags.IsIndirect && Subtarget.isUsingPCRelativeCalls())) &&
5890 "Expecting a global address, external symbol, absolute value, "
5891 "register or an indirect tail call when PC Relative calls are "
5895 "Unexpected call opcode for a tail call.");
5902 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5903 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes,
Ops);
5915 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5918 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5938 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5939 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5943bool PPCTargetLowering::isEligibleForTCO(
5948 bool isCalleeExternalSymbol)
const {
5952 if (Subtarget.
isSVR4ABI() && Subtarget.isPPC64())
5953 return IsEligibleForTailCallOptimization_64SVR4(
5954 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5955 isCalleeExternalSymbol);
5957 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5985 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
6000 "Callee should be an llvm::Function object.");
6003 <<
"\nTCO callee: ");
6010 "site marked musttail");
6017 Callee = LowerGlobalAddress(Callee, DAG);
6020 CallConv, isTailCall, isVarArg, isPatchPoint,
6023 Subtarget.is64BitELFABI() &&
6027 if (Subtarget.isAIXABI())
6028 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6031 assert(Subtarget.isSVR4ABI());
6032 if (Subtarget.isPPC64())
6033 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6035 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6039SDValue PPCTargetLowering::LowerCall_32SVR4(
6050 const bool IsVarArg = CFlags.IsVarArg;
6051 const bool IsTailCall = CFlags.IsTailCall;
6057 const Align PtrAlign(4);
6068 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6076 CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.
getContext());
6079 CCInfo.AllocateStack(Subtarget.getFrameLowering()->getLinkageSize(),
6086 unsigned NumArgs = Outs.
size();
6088 for (
unsigned i = 0; i != NumArgs; ++i) {
6089 MVT ArgVT = Outs[i].VT;
6090 ISD::ArgFlagsTy ArgFlags = Outs[i].Flags;
6095 Outs[i].OrigTy, CCInfo);
6098 ArgFlags, Outs[i].OrigTy, CCInfo);
6103 errs() <<
"Call operand #" << i <<
" has unhandled type "
6116 CCState CCByValInfo(CallConv, IsVarArg, MF, ByValArgLocs, *DAG.
getContext());
6119 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6126 unsigned NumBytes = CCByValInfo.getStackSize();
6140 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6151 bool seenFloatArg =
false;
6156 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6158 ++i, ++RealArgIdx) {
6159 CCValAssign &VA = ArgLocs[i];
6160 SDValue Arg = OutVals[RealArgIdx];
6161 ISD::ArgFlagsTy
Flags = Outs[RealArgIdx].Flags;
6163 if (
Flags.isByVal()) {
6168 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6169 CCValAssign &ByValVA = ByValArgLocs[
j++];
6191 Chain = CallSeqStart = NewCallSeqStart;
6210 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6211 bool IsLE = Subtarget.isLittleEndian();
6217 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6232 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
6241 if (!MemOpChains.
empty())
6247 for (
const auto &[
Reg,
N] : RegsToPass) {
6255 SDVTList VTs = DAG.
getVTList(MVT::Other, MVT::Glue);
6268 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6269 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6274SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6286 return NewCallSeqStart;
6289SDValue PPCTargetLowering::LowerCall_64SVR4(
6296 bool isELFv2ABI = Subtarget.isELFv2ABI();
6297 bool isLittleEndian = Subtarget.isLittleEndian();
6299 bool IsSibCall =
false;
6303 unsigned PtrByteSize = 8;
6316 MF.
getInfo<PPCFunctionInfo>()->setHasFastCall();
6318 assert(!(IsFastCall && CFlags.IsVarArg) &&
6319 "fastcc not supported on varargs functions");
6325 unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
6326 unsigned NumBytes = LinkageSize;
6327 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6330 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6331 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6334 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6335 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6338 const unsigned NumGPRs = std::size(GPR);
6340 const unsigned NumVRs = std::size(VR);
6346 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6347 if (!HasParameterArea) {
6348 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6349 unsigned AvailableFPRs = NumFPRs;
6350 unsigned AvailableVRs = NumVRs;
6351 unsigned NumBytesTmp = NumBytes;
6352 for (
unsigned i = 0; i !=
NumOps; ++i) {
6353 if (Outs[i].
Flags.isNest())
continue;
6355 PtrByteSize, LinkageSize, ParamAreaSize,
6356 NumBytesTmp, AvailableFPRs, AvailableVRs))
6357 HasParameterArea =
true;
6363 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6368 HasParameterArea =
false;
6371 for (
unsigned i = 0; i !=
NumOps; ++i) {
6372 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6373 EVT ArgVT = Outs[i].VT;
6374 EVT OrigVT = Outs[i].ArgVT;
6380 if (
Flags.isByVal()) {
6381 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6382 if (NumGPRsUsed > NumGPRs)
6383 HasParameterArea =
true;
6390 if (++NumGPRsUsed <= NumGPRs)
6400 if (++NumVRsUsed <= NumVRs)
6404 if (++NumVRsUsed <= NumVRs)
6409 if (++NumFPRsUsed <= NumFPRs)
6413 HasParameterArea =
true;
6420 NumBytes =
alignTo(NumBytes, Alignement);
6423 if (
Flags.isInConsecutiveRegsLast())
6424 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6427 unsigned NumBytesActuallyUsed = NumBytes;
6437 if (HasParameterArea)
6438 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6440 NumBytes = LinkageSize;
6455 if (CFlags.IsTailCall)
6467 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6478 unsigned ArgOffset = LinkageSize;
6484 for (
unsigned i = 0; i !=
NumOps; ++i) {
6486 ISD::ArgFlagsTy
Flags = Outs[i].Flags;
6487 EVT ArgVT = Outs[i].VT;
6488 EVT OrigVT = Outs[i].ArgVT;
6497 auto ComputePtrOff = [&]() {
6501 ArgOffset =
alignTo(ArgOffset, Alignment);
6512 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6513 GPR_idx = std::min(GPR_idx, NumGPRs);
6520 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6526 if (
Flags.isByVal()) {
6544 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6545 if (GPR_idx != NumGPRs) {
6547 MachinePointerInfo(), VT);
6549 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6551 ArgOffset += PtrByteSize;
6556 if (GPR_idx == NumGPRs &&
Size < 8) {
6558 if (!isLittleEndian) {
6563 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6566 ArgOffset += PtrByteSize;
6575 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6576 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6581 if (
Size < 8 && GPR_idx != NumGPRs) {
6591 if (!isLittleEndian) {
6595 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6601 DAG.
getLoad(PtrVT, dl, Chain, PtrOff, MachinePointerInfo());
6603 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6606 ArgOffset += PtrByteSize;
6612 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6615 if (GPR_idx != NumGPRs) {
6616 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6619 MachinePointerInfo(), ObjType);
6622 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6623 ArgOffset += PtrByteSize;
6625 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6637 if (
Flags.isNest()) {
6639 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6646 if (GPR_idx != NumGPRs) {
6647 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6652 assert(HasParameterArea &&
6653 "Parameter area must exist to pass an argument in memory.");
6655 true, CFlags.IsTailCall,
false, MemOpChains,
6656 TailCallArguments, dl);
6658 ArgOffset += PtrByteSize;
6661 ArgOffset += PtrByteSize;
6674 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6675 bool NeededLoad =
false;
6678 if (FPR_idx != NumFPRs)
6679 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6682 if (!NeedGPROrStack)
6684 else if (GPR_idx != NumGPRs && !IsFastCall) {
6695 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i64, Arg);
6698 }
else if (!
Flags.isInConsecutiveRegs()) {
6699 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6704 }
else if (ArgOffset % PtrByteSize != 0) {
6706 Lo = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, OutVals[i - 1]);
6707 Hi = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6708 if (!isLittleEndian)
6713 }
else if (
Flags.isInConsecutiveRegsLast()) {
6714 ArgVal = DAG.
getNode(ISD::BITCAST, dl, MVT::i32, Arg);
6716 if (!isLittleEndian)
6726 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6734 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6739 assert(HasParameterArea &&
6740 "Parameter area must exist to pass an argument in memory.");
6742 true, CFlags.IsTailCall,
false, MemOpChains,
6743 TailCallArguments, dl);
6750 if (!IsFastCall || NeededLoad) {
6752 Flags.isInConsecutiveRegs()) ? 4 : 8;
6753 if (
Flags.isInConsecutiveRegsLast())
6754 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6774 if (CFlags.IsVarArg) {
6775 assert(HasParameterArea &&
6776 "Parameter area must exist if we have a varargs call.");
6780 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
6782 if (VR_idx != NumVRs) {
6784 DAG.
getLoad(MVT::v4f32, dl, Store, PtrOff, MachinePointerInfo());
6786 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6789 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6790 if (GPR_idx == NumGPRs)
6795 DAG.
getLoad(PtrVT, dl, Store, Ix, MachinePointerInfo());
6797 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6803 if (VR_idx != NumVRs) {
6804 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6809 assert(HasParameterArea &&
6810 "Parameter area must exist to pass an argument in memory.");
6812 true, CFlags.IsTailCall,
true, MemOpChains,
6813 TailCallArguments, dl);
6824 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6825 "mismatch in size of parameter area");
6826 (void)NumBytesActuallyUsed;
6828 if (!MemOpChains.
empty())
6834 if (CFlags.IsIndirect) {
6838 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6843 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
6853 if (isELFv2ABI && !CFlags.IsPatchPoint)
6854 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6860 for (
const auto &[
Reg,
N] : RegsToPass) {
6865 if (CFlags.IsTailCall && !IsSibCall)
6869 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6870 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6877 "Required alignment greater than stack alignment.");
6897 return RequiredAlign <= 8;
6902 return RequiredAlign <= 4;
6910 State.getMachineFunction().getSubtarget());
6911 const bool IsPPC64 = Subtarget.isPPC64();
6912 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6913 const Align PtrAlign(PtrSize);
6914 const Align StackAlign(16);
6917 if (ValVT == MVT::f128)
6921 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6922 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6924 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6925 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6928 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6929 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6930 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6935 MCRegister EnvReg = State.AllocateReg(IsPPC64 ? PPC::X11 : PPC::R11);
6944 if (ByValAlign > StackAlign)
6946 "16 are not supported.");
6949 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6953 if (ByValSize == 0) {
6955 State.getStackSize(), RegVT, LocInfo));
6960 unsigned NextReg = State.getFirstUnallocated(GPRs);
6961 while (NextReg != GPRs.
size() &&
6966 State.AllocateStack(PtrSize, PtrAlign);
6967 assert(
Reg &&
"Alocating register unexpectedly failed.");
6969 NextReg = State.getFirstUnallocated(GPRs);
6972 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6973 unsigned Offset = State.AllocateStack(StackSize, ObjAlign);
6993 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6997 const unsigned Offset = State.AllocateStack(PtrSize, PtrAlign);
7016 State.AllocateStack(IsPPC64 ? 8 : StoreSize,
Align(4));
7022 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
7024 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
7025 if (State.isVarArg()) {
7057 const unsigned VecSize = 16;
7058 const Align VecAlign(VecSize);
7060 if (!State.isVarArg()) {
7063 if (
MCRegister VReg = State.AllocateReg(VR)) {
7070 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7075 unsigned NextRegIndex = State.getFirstUnallocated(GPRs);
7078 while (NextRegIndex != GPRs.
size() &&
7082 State.AllocateStack(PtrSize, PtrAlign);
7083 assert(
Reg &&
"Allocating register unexpectedly failed.");
7085 NextRegIndex = State.getFirstUnallocated(GPRs);
7093 if (
MCRegister VReg = State.AllocateReg(VR)) {
7096 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7097 State.AllocateReg(GPRs);
7098 State.AllocateStack(VecSize, VecAlign);
7102 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7108 if (NextRegIndex == GPRs.
size()) {
7109 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7117 if (GPRs[NextRegIndex] == PPC::R9) {
7118 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7122 const MCRegister FirstReg = State.AllocateReg(PPC::R9);
7123 const MCRegister SecondReg = State.AllocateReg(PPC::R10);
7124 assert(FirstReg && SecondReg &&
7125 "Allocating R9 or R10 unexpectedly failed.");
7136 const unsigned Offset = State.AllocateStack(VecSize, VecAlign);
7139 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7141 assert(
Reg &&
"Failed to allocated register for vararg vector argument");
7156 assert((IsPPC64 || SVT != MVT::i64) &&
7157 "i64 should have been split for 32-bit codegen.");
7165 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7167 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7169 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7177 return &PPC::VRRCRegClass;
7190 else if (Flags.isZExt())
7202 "Reg must be a valid argument register!");
7203 return LASize + 4 * (
Reg - PPC::R3);
7208 "Reg must be a valid argument register!");
7209 return LASize + 8 * (
Reg - PPC::X3);
7255SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7262 "Unexpected calling convention!");
7270 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7272 const bool IsPPC64 = Subtarget.isPPC64();
7273 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7279 PPCFunctionInfo *FuncInfo = MF.
getInfo<PPCFunctionInfo>();
7280 CCState CCInfo(CallConv, isVarArg, MF, ArgLocs, *DAG.
getContext());
7284 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7285 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7286 uint64_t SaveStackPos = CCInfo.getStackSize();
7288 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7292 for (
size_t I = 0, End = ArgLocs.
size();
I != End; ) {
7293 CCValAssign &VA = ArgLocs[
I++];
7299 bool ArgSignExt =
Ins[VA.
getValNo()].Flags.isSExt();
7311 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7313 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7319 MachinePointerInfo(),
Align(PtrByteSize));
7325 unsigned StoreSize =
7327 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7330 auto HandleMemLoc = [&]() {
7333 assert((ValSize <= LocSize) &&
7334 "Object size is larger than size of MemLoc");
7337 if (LocSize > ValSize)
7338 CurArgOffset += LocSize - ValSize;
7340 const bool IsImmutable =
7346 DAG.
getLoad(ValVT, dl, Chain, FIN, MachinePointerInfo());
7380 assert(isVarArg &&
"Only use custom memloc for vararg.");
7383 const unsigned OriginalValNo = VA.
getValNo();
7384 (void)OriginalValNo;
7386 auto HandleCustomVecRegLoc = [&]() {
7387 assert(
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7388 "Missing custom RegLoc.");
7391 "Unexpected Val type for custom RegLoc.");
7393 "ValNo mismatch between custom MemLoc and RegLoc.");
7397 Subtarget.hasVSX()));
7404 HandleCustomVecRegLoc();
7405 HandleCustomVecRegLoc();
7409 if (
I != End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7411 "Only 2 custom RegLocs expected for 64-bit codegen.");
7412 HandleCustomVecRegLoc();
7413 HandleCustomVecRegLoc();
7457 const unsigned Size =
7469 if (
Flags.isByVal()) {
7473 const PPCFrameLowering *FL = Subtarget.getFrameLowering();
7475 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7483 const TargetRegisterClass *RegClass =
7484 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7486 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7499 CopyFrom.
getValue(1), dl, CopyFrom,
7509 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7512 "RegLocs should be for ByVal argument.");
7514 const CCValAssign RL = ArgLocs[
I++];
7519 if (
Offset != StackSize) {
7521 "Expected MemLoc for remaining bytes.");
7522 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7536 Subtarget.hasVSX()));
7553 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7555 unsigned CallerReservedArea = std::max<unsigned>(
7556 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7562 CallerReservedArea =
7571 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7572 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7574 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7575 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7576 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7581 for (
unsigned GPRIndex =
7582 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7583 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7586 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7587 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7599 if (!MemOps.
empty())
7605SDValue PPCTargetLowering::LowerCall_AIX(
7618 "Unexpected calling convention!");
7620 if (CFlags.IsPatchPoint)
7623 const PPCSubtarget &Subtarget = DAG.
getSubtarget<PPCSubtarget>();
7627 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7634 const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
7635 const bool IsPPC64 = Subtarget.isPPC64();
7637 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7638 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7639 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7647 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7648 const unsigned NumBytes = std::max<unsigned>(
7649 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7665 for (
unsigned I = 0,
E = ArgLocs.
size();
I !=
E;) {
7666 const unsigned ValNo = ArgLocs[
I].getValNo();
7668 ISD::ArgFlagsTy
Flags = Outs[ValNo].Flags;
7670 if (
Flags.isByVal()) {
7671 const unsigned ByValSize =
Flags.getByValSize();
7679 auto GetLoad = [&](EVT VT,
unsigned LoadOffset) {
7685 MachinePointerInfo(), VT);
7688 unsigned LoadOffset = 0;
7691 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7694 LoadOffset += PtrByteSize;
7695 const CCValAssign &ByValVA = ArgLocs[
I++];
7697 "Unexpected location for pass-by-value argument.");
7701 if (LoadOffset == ByValSize)
7705 assert(ArgLocs[
I].getValNo() == ValNo &&
7706 "Expected additional location for by-value argument.");
7708 if (ArgLocs[
I].isMemLoc()) {
7709 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7710 const CCValAssign &ByValVA = ArgLocs[
I++];
7711 ISD::ArgFlagsTy MemcpyFlags =
Flags;
7714 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7720 CallSeqStart, MemcpyFlags, DAG, dl);
7729 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7730 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7731 "Unexpected register residue for by-value argument.");
7733 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7737 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7747 "Unexpected load emitted during handling of pass-by-value "
7755 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7760 const CCValAssign &ByValVA = ArgLocs[
I++];
7765 CCValAssign &VA = ArgLocs[
I++];
7790 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7796 DAG.
getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
7798 const unsigned OriginalValNo = VA.
getValNo();
7800 unsigned LoadOffset = 0;
7801 auto HandleCustomVecRegLoc = [&]() {
7802 assert(
I !=
E &&
"Unexpected end of CCvalAssigns.");
7803 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7804 "Expected custom RegLoc.");
7805 CCValAssign RegVA = ArgLocs[
I++];
7807 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7813 LoadOffset += PtrByteSize;
7819 HandleCustomVecRegLoc();
7820 HandleCustomVecRegLoc();
7822 if (
I !=
E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7823 ArgLocs[
I].getValNo() == OriginalValNo) {
7825 "Only 2 custom RegLocs expected for 64-bit codegen.");
7826 HandleCustomVecRegLoc();
7827 HandleCustomVecRegLoc();
7838 DAG.
getStore(Chain, dl, Arg, PtrOff,
7840 Subtarget.getFrameLowering()->getStackAlign()));
7847 "Unexpected register handling for calling convention.");
7853 "Custom register handling only expected for VarArg.");
7858 if (Arg.getValueType().getStoreSize() == LocVT.
getStoreSize())
7862 else if (Arg.getValueType().getFixedSizeInBits() <
7870 assert(Arg.getValueType() == MVT::f64 && CFlags.IsVarArg && !IsPPC64 &&
7871 "Unexpected custom register for argument!");
7872 CCValAssign &GPR1 = VA;
7881 CCValAssign &PeekArg = ArgLocs[
I];
7884 CCValAssign &GPR2 = ArgLocs[
I++];
7892 if (!MemOpChains.
empty())
7897 if (CFlags.IsIndirect) {
7898 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7899 const MCRegister TOCBaseReg = Subtarget.getTOCPointerRegister();
7900 const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
7901 const MVT PtrVT = Subtarget.getScalarIntVT();
7902 const unsigned TOCSaveOffset =
7903 Subtarget.getFrameLowering()->getTOCSaveOffset();
7918 for (
auto Reg : RegsToPass) {
7923 const int SPDiff = 0;
7924 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7925 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7933 const Type *RetTy)
const {
7935 CCState CCInfo(CallConv, isVarArg, MF, RVLocs,
Context);
7936 return CCInfo.CheckReturn(
7951 CCInfo.AnalyzeReturn(Outs,
7960 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7961 CCValAssign &VA = RVLocs[i];
7964 SDValue Arg = OutVals[RealResIdx];
7979 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7980 bool isLittleEndian = Subtarget.isLittleEndian();
8002 RetOps.push_back(Glue);
8008PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
8013 EVT IntVT =
Op.getValueType();
8017 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8033 bool isPPC64 = Subtarget.isPPC64();
8034 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
8043 DAG.
getLoad(PtrVT, dl, Chain, StackPtr, MachinePointerInfo());
8049 return DAG.
getStore(Chain, dl, LoadLinkSP, StackPtr, MachinePointerInfo());
8054 bool isPPC64 = Subtarget.isPPC64();
8059 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8065 int LROffset = Subtarget.getFrameLowering()->getReturnSaveOffset();
8075PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8077 bool isPPC64 = Subtarget.isPPC64();
8082 PPCFunctionInfo *FI = MF.
getInfo<PPCFunctionInfo>();
8088 int FPOffset = Subtarget.getFrameLowering()->getFramePointerSaveOffset();
8111 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8113 SDVTList VTs = DAG.
getVTList(PtrVT, MVT::Other);
8123 bool isPPC64 = Subtarget.isPPC64();
8135 Op.getOperand(0),
Op.getOperand(1));
8142 Op.getOperand(0),
Op.getOperand(1));
8146 if (
Op.getValueType().isVector())
8147 return LowerVectorLoad(
Op, DAG);
8149 assert(
Op.getValueType() == MVT::i1 &&
8150 "Custom lowering only for i1 loads");
8159 MachineMemOperand *MMO =
LD->getMemOperand();
8163 BasePtr, MVT::i8, MMO);
8171 if (
Op.getOperand(1).getValueType().isVector())
8172 return LowerVectorStore(
Op, DAG);
8174 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8175 "Custom lowering only for i1 stores");
8185 MachineMemOperand *MMO =
ST->getMemOperand();
8194 assert(
Op.getValueType() == MVT::i1 &&
8195 "Custom lowering only for i1 results");
8223 EVT TrgVT =
Op.getValueType();
8247 if (SrcSize == 256) {
8258 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8264 SmallVector<int, 16> ShuffV;
8265 if (Subtarget.isLittleEndian())
8266 for (
unsigned i = 0; i < TrgNumElts; ++i)
8269 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8273 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8277 Op1 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op1);
8278 Op2 = DAG.
getNode(ISD::BITCAST,
DL, WideVT, Op2);
8286 EVT ResVT =
Op.getValueType();
8287 EVT CmpVT =
Op.getOperand(0).getValueType();
8289 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8295 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8308 SDNodeFlags
Flags =
Op.getNode()->getFlags();
8312 if (Subtarget.hasP9Vector() &&
LHS == TV &&
RHS == FV) {
8344 if (
LHS.getValueType() == MVT::f32)
8348 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8350 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), Sel1, FV);
8357 if (
LHS.getValueType() == MVT::f32)
8366 if (
LHS.getValueType() == MVT::f32)
8369 DAG.
getNode(ISD::FNEG, dl, MVT::f64,
LHS), TV, FV);
8380 if (
Cmp.getValueType() == MVT::f32)
8381 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8384 Sel1 = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Sel1);
8386 DAG.
getNode(ISD::FNEG, dl, MVT::f64, Cmp), Sel1, FV);
8390 if (
Cmp.getValueType() == MVT::f32)
8391 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8396 if (
Cmp.getValueType() == MVT::f32)
8397 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8402 if (
Cmp.getValueType() == MVT::f32)
8403 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8408 if (
Cmp.getValueType() == MVT::f32)
8409 Cmp = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Cmp);
8441 bool IsStrict =
Op->isStrictFPOpcode();
8450 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8452 MVT DestTy =
Op.getSimpleValueType();
8453 assert(Src.getValueType().isFloatingPoint() &&
8454 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8455 DestTy == MVT::i64) &&
8456 "Invalid FP_TO_INT types");
8457 if (Src.getValueType() == MVT::f32) {
8461 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8464 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
8466 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8476 assert((IsSigned || Subtarget.hasFPCVT()) &&
8477 "i64 FP_TO_UINT is supported only with FPCVT");
8480 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8492void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8494 const SDLoc &dl)
const {
8498 bool IsStrict =
Op->isStrictFPOpcode();
8501 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8502 (IsSigned || Subtarget.hasFPCVT());
8505 MachinePointerInfo MPI =
8513 Alignment =
Align(4);
8514 MachineMemOperand *MMO =
8520 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8524 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8525 !Subtarget.isLittleEndian()) {
8534 RLI.Alignment = Alignment;
8542 const SDLoc &dl)
const {
8545 if (
Op->isStrictFPOpcode())
8552 const SDLoc &dl)
const {
8553 bool IsStrict =
Op->isStrictFPOpcode();
8556 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8557 EVT SrcVT = Src.getValueType();
8558 EVT DstVT =
Op.getValueType();
8561 if (SrcVT == MVT::f128)
8562 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8566 if (SrcVT == MVT::ppcf128) {
8567 if (DstVT == MVT::i32) {
8572 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8583 {Op.getOperand(0), Lo, Hi}, Flags);
8586 {Res.getValue(1), Res}, Flags);
8592 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8616 {Chain, Src, FltOfs}, Flags);
8620 {Chain, Val}, Flags);
8623 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8641 if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
8642 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8645 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8647 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8648 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8659bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8664 if (
Op->isStrictFPOpcode())
8669 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8673 Op.getOperand(0).getValueType())) {
8675 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8680 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8681 LD->isNonTemporal())
8683 if (
LD->getMemoryVT() != MemVT)
8693 RLI.Ptr =
LD->getBasePtr();
8694 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8696 "Non-pre-inc AM on PPC?");
8701 RLI.Chain =
LD->getChain();
8702 RLI.MPI =
LD->getPointerInfo();
8703 RLI.IsDereferenceable =
LD->isDereferenceable();
8704 RLI.IsInvariant =
LD->isInvariant();
8705 RLI.Alignment =
LD->getAlign();
8706 RLI.AAInfo =
LD->getAAInfo();
8707 RLI.Ranges =
LD->getRanges();
8709 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8716bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8717 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8724 if (!Subtarget.hasP9Vector() &&
8728 for (SDUse &Use : Origin->
uses()) {
8731 if (
Use.getResNo() != 0)
8758 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8761 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8762 if (
Op->isStrictFPOpcode()) {
8764 Chain =
Op.getOperand(0);
8766 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8768 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8776 const SDLoc &dl)
const {
8777 assert((
Op.getValueType() == MVT::f32 ||
8778 Op.getValueType() == MVT::f64) &&
8779 "Invalid floating point type as target of conversion");
8780 assert(Subtarget.hasFPCVT() &&
8781 "Int to FP conversions with direct moves require FPCVT");
8782 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8783 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8805 for (
unsigned i = 1; i < NumConcat; ++i)
8812 const SDLoc &dl)
const {
8813 bool IsStrict =
Op->isStrictFPOpcode();
8814 unsigned Opc =
Op.getOpcode();
8815 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8818 "Unexpected conversion type");
8819 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8820 "Supports conversions to v2f64/v4f32 only.");
8824 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8827 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8832 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8834 SmallVector<int, 16> ShuffV;
8835 for (
unsigned i = 0; i < WideNumElts; ++i)
8838 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8839 int SaveElts = FourEltRes ? 4 : 2;
8840 if (Subtarget.isLittleEndian())
8841 for (
int i = 0; i < SaveElts; i++)
8842 ShuffV[i * Stride] = i;
8844 for (
int i = 1; i <= SaveElts; i++)
8845 ShuffV[i * Stride - 1] = i - 1;
8853 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8854 EVT ExtVT = Src.getValueType();
8855 if (Subtarget.hasP9Altivec())
8862 Extend = DAG.
getNode(ISD::BITCAST, dl, IntermediateVT, Arrange);
8866 {Op.getOperand(0), Extend}, Flags);
8868 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8876 bool IsStrict =
Op->isStrictFPOpcode();
8877 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8882 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8884 EVT InVT = Src.getValueType();
8885 EVT OutVT =
Op.getValueType();
8888 return LowerINT_TO_FPVector(
Op, DAG, dl);
8891 if (
Op.getValueType() == MVT::f128)
8892 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8895 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8898 if (Src.getValueType() == MVT::i1) {
8910 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8911 Subtarget.isPPC64() && Subtarget.hasFPCVT())
8912 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8914 assert((IsSigned || Subtarget.hasFPCVT()) &&
8915 "UINT_TO_FP is supported only with FPCVT");
8917 if (Src.getValueType() == MVT::i64) {
8932 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT() &&
8933 !
Op->getFlags().hasApproximateFuncs()) {
8973 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8974 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8975 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8978 }
else if (Subtarget.hasLFIWAX() &&
8979 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8980 MachineMemOperand *MMO =
8982 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8986 Ops, MVT::i32, MMO);
8989 }
else if (Subtarget.hasFPCVT() &&
8990 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8991 MachineMemOperand *MMO =
8993 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8997 Ops, MVT::i32, MMO);
9000 }
else if (((Subtarget.hasLFIWAX() &&
9002 (Subtarget.hasFPCVT() &&
9017 "Expected an i32 store");
9023 RLI.Alignment =
Align(4);
9025 MachineMemOperand *MMO =
9027 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9031 dl, DAG.
getVTList(MVT::f64, MVT::Other),
9032 Ops, MVT::i32, MMO);
9033 Chain =
Bits.getValue(1);
9035 Bits = DAG.
getNode(ISD::BITCAST, dl, MVT::f64, SINT);
9041 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9045 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9054 assert(Src.getValueType() == MVT::i32 &&
9055 "Unhandled INT_TO_FP type in custom expander!");
9065 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9068 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9078 "Expected an i32 store");
9084 RLI.Alignment =
Align(4);
9087 MachineMemOperand *MMO =
9089 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9095 if (ReusingLoad && RLI.ResChain) {
9099 assert(Subtarget.isPPC64() &&
9100 "i32->FP without LFIWAX supported only on PPC64");
9109 Chain, dl, Ext64, FIdx,
9115 MVT::f64, dl, Chain, FIdx,
9124 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9128 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9145 uint64_t
Mode = CVal->getZExtValue();
9146 assert(
Mode < 4 &&
"Unsupported rounding mode!");
9147 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9148 if (Subtarget.isISA3_0())
9151 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9152 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9155 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9156 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9158 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9176 if (!Subtarget.isISA3_0()) {
9178 Chain =
MFFS.getValue(1);
9181 if (Subtarget.isPPC64()) {
9182 if (Subtarget.isISA3_0()) {
9187 PPC::RLDIMI, Dl, MVT::i64,
9188 {DAG.
getNode(ISD::BITCAST, Dl, MVT::i64, MFFS),
9192 NewFPSCR =
SDValue(InsertRN, 0);
9194 NewFPSCR = DAG.
getNode(ISD::BITCAST, Dl, MVT::f64, NewFPSCR);
9199 SDValue Addr = Subtarget.isLittleEndian()
9203 if (Subtarget.isISA3_0()) {
9204 Chain = DAG.
getStore(Chain, Dl, DstFlag, Addr, MachinePointerInfo());
9206 Chain = DAG.
getStore(Chain, Dl, MFFS, StackSlot, MachinePointerInfo());
9208 DAG.
getLoad(MVT::i32, Dl, Chain, Addr, MachinePointerInfo());
9211 PPC::RLWIMI, Dl, MVT::i32,
9212 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9213 DAG.getTargetConstant(30, Dl, MVT::i32),
9214 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9216 Chain = DAG.
getStore(Chain, Dl, Tmp, Addr, MachinePointerInfo());
9219 DAG.
getLoad(MVT::f64, Dl, Chain, StackSlot, MachinePointerInfo());
9222 if (Subtarget.isISA3_0())
9228 PPC::MTFSF, Dl, MVT::Other,
9256 EVT VT =
Op.getValueType();
9262 Chain =
MFFS.getValue(1);
9267 DAG.
getNode(ISD::BITCAST, dl, MVT::i64, MFFS));
9272 Chain = DAG.
getStore(Chain, dl, MFFS, StackSlot, MachinePointerInfo());
9276 "Stack slot adjustment is valid only on big endian subtargets!");
9279 CWD = DAG.
getLoad(MVT::i32, dl, Chain, Addr, MachinePointerInfo());
9306 EVT VT =
Op.getValueType();
9310 VT ==
Op.getOperand(1).getValueType() &&
9330 SDValue OutOps[] = { OutLo, OutHi };
9335 EVT VT =
Op.getValueType();
9339 VT ==
Op.getOperand(1).getValueType() &&
9359 SDValue OutOps[] = { OutLo, OutHi };
9365 EVT VT =
Op.getValueType();
9368 VT ==
Op.getOperand(1).getValueType() &&
9388 SDValue OutOps[] = { OutLo, OutHi };
9395 EVT VT =
Op.getValueType();
9402 EVT AmtVT =
Z.getValueType();
9425 static const MVT VTys[] = {
9426 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9429 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9432 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9437 EVT CanonicalVT = VTys[SplatSize-1];
9450 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9451 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9460 EVT DestVT = MVT::Other) {
9461 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9470 EVT DestVT = MVT::Other) {
9473 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9485 for (
unsigned i = 0; i != 16; ++i)
9488 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
9506 EVT VecVT = V->getValueType(0);
9507 bool RightType = VecVT == MVT::v2f64 ||
9508 (HasP8Vector && VecVT == MVT::v4f32) ||
9509 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9513 bool IsSplat =
true;
9514 bool IsLoad =
false;
9520 if (V->isConstant())
9522 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9523 if (V->getOperand(i).isUndef())
9527 if (V->getOperand(i).getOpcode() == ISD::LOAD ||
9529 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9531 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD) ||
9533 V->getOperand(i).getOperand(0).getOpcode() == ISD::LOAD))
9537 if (V->getOperand(i) != Op0 ||
9538 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9541 return !(IsSplat && IsLoad);
9551 (
Op.getValueType() != MVT::f128))
9556 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9559 if (!Subtarget.isLittleEndian())
9567 while (InputLoad->
getOpcode() == ISD::BITCAST)
9574 if (InputLoad->
getOpcode() != ISD::LOAD)
9584 APFloat APFloatToConvert = ArgAPFloat;
9585 bool LosesInfo =
true;
9590 ArgAPFloat = APFloatToConvert;
9612 APFloat APFloatToConvert = ArgAPFloat;
9613 bool LosesInfo =
true;
9617 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9626 EVT Ty =
Op->getValueType(0);
9629 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9638 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9642 if (Ty == MVT::v2i64) {
9645 if (MemVT == MVT::i32) {
9657 bool IsLittleEndian) {
9663 APInt ConstValue(VTSize, 0);
9667 unsigned BitPos = 0;
9675 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9676 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9680 for (
unsigned J = 0; J < 16; ++J) {
9682 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9684 if (ExtractValue == 0xFF)
9699 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9701 if (Subtarget.hasP10Vector()) {
9702 APInt BitMask(32, 0);
9708 BitMask != 0 && BitMask != 0xffff) {
9710 MachineSDNode *MSDNode =
9716 SDV = DAG.
getNode(ISD::BITCAST, dl, DVT, SDV);
9722 if (
SDValue VecPat = combineBVLoadsSpecialValue(
Op, DAG))
9726 APInt APSplatBits, APSplatUndef;
9727 unsigned SplatBitSize;
9729 bool BVNIsConstantSplat =
9731 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
9737 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9738 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9741 if ((
Op->getValueType(0) == MVT::v2f64) &&
9774 bool IsSplat64 =
false;
9775 uint64_t SplatBits = 0;
9776 int32_t SextVal = 0;
9777 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9779 if (SplatBitSize <= 32) {
9781 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9782 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9783 bool P9Vector = Subtarget.hasP9Vector();
9784 int32_t
Hi = P9Vector ? 127 : 15;
9785 int32_t
Lo = P9Vector ? -128 : -16;
9786 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9787 SextVal =
static_cast<int32_t
>(SplatBits);
9791 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9798 const SDValue *InputLoad = &
Op.getOperand(0);
9803 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9804 unsigned ElementSize =
9807 assert(((ElementSize == 2 * MemorySize)
9811 "Unmatched element size and opcode!\n");
9816 unsigned NumUsesOfInputLD = 128 / ElementSize;
9818 if (BVInOp.isUndef())
9833 if (NumUsesOfInputLD == 1 &&
9835 !Subtarget.isLittleEndian() && Subtarget.hasVSX() &&
9836 Subtarget.hasLFIWAX()))
9844 if (NumUsesOfInputLD == 1 && Subtarget.isLittleEndian() &&
9845 Subtarget.isISA3_1() && ElementSize <= 16)
9848 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9850 Subtarget.hasVSX()) {
9857 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other),
Ops,
9858 LD->getMemoryVT(),
LD->getMemOperand());
9870 if (Subtarget.hasVSX() && Subtarget.isPPC64() &&
9872 Subtarget.hasP8Vector()))
9878 unsigned SplatSize = SplatBitSize / 8;
9883 if (SplatBits == 0) {
9885 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9887 Op = DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Z);
9897 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9899 Op.getValueType(), DAG, dl);
9901 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9906 if (Subtarget.hasP9Vector() && SplatSize == 1)
9912 if (SextVal >= -16 && SextVal <= 15) {
9915 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9925 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9931 switch (SplatSize) {
9935 IID = Intrinsic::ppc_altivec_vupklsb;
9939 IID = Intrinsic::ppc_altivec_vextsb2w;
9943 IID = Intrinsic::ppc_altivec_vextsb2d;
9950 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9959 if (SextVal >= -32 && SextVal <= 31) {
9964 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9965 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9968 if (VT ==
Op.getValueType())
9971 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), RetVal);
9977 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9987 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
9991 static const signed char SplatCsts[] = {
9992 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9993 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9996 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9999 int i = SplatCsts[idx];
10003 unsigned TypeShiftAmt = i & (SplatBitSize-1);
10006 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
10008 static const unsigned IIDs[] = {
10009 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
10010 Intrinsic::ppc_altivec_vslw
10013 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
10017 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
10019 static const unsigned IIDs[] = {
10020 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
10021 Intrinsic::ppc_altivec_vsrw
10024 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
10028 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
10029 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
10031 static const unsigned IIDs[] = {
10032 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
10033 Intrinsic::ppc_altivec_vrlw
10036 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Res);
10040 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
10042 unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
10046 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10048 unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
10052 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10054 unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
10067 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10068 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10069 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10085 if (LHSID == (1*9+2)*9+3)
return LHS;
10086 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10098 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10099 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10100 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10101 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10104 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10105 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10106 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10107 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10110 for (
unsigned i = 0; i != 16; ++i)
10111 ShufIdxs[i] = (i&3)+0;
10114 for (
unsigned i = 0; i != 16; ++i)
10115 ShufIdxs[i] = (i&3)+4;
10118 for (
unsigned i = 0; i != 16; ++i)
10119 ShufIdxs[i] = (i&3)+8;
10122 for (
unsigned i = 0; i != 16; ++i)
10123 ShufIdxs[i] = (i&3)+12;
10133 OpLHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpLHS);
10134 OpRHS = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OpRHS);
10136 return DAG.
getNode(ISD::BITCAST, dl, VT,
T);
10144 const unsigned BytesInVector = 16;
10145 bool IsLE = Subtarget.isLittleEndian();
10149 unsigned ShiftElts = 0, InsertAtByte = 0;
10153 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10154 0, 15, 14, 13, 12, 11, 10, 9};
10155 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10156 1, 2, 3, 4, 5, 6, 7, 8};
10158 ArrayRef<int>
Mask =
N->getMask();
10159 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10171 bool FoundCandidate =
false;
10175 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10178 for (
unsigned i = 0; i < BytesInVector; ++i) {
10179 unsigned CurrentElement =
Mask[i];
10182 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10185 bool OtherElementsInOrder =
true;
10188 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10195 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10196 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10197 OtherElementsInOrder =
false;
10204 if (OtherElementsInOrder) {
10211 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10212 : BigEndianShifts[CurrentElement & 0xF];
10213 Swap = CurrentElement < BytesInVector;
10215 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10216 FoundCandidate =
true;
10221 if (!FoundCandidate)
10245 const unsigned NumHalfWords = 8;
10246 const unsigned BytesInVector = NumHalfWords * 2;
10251 bool IsLE = Subtarget.isLittleEndian();
10255 unsigned ShiftElts = 0, InsertAtByte = 0;
10259 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10260 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10263 uint32_t OriginalOrderLow = 0x1234567;
10264 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10267 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10268 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10285 bool FoundCandidate =
false;
10288 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10289 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10291 uint32_t MaskOtherElts = ~(0xF <<
MaskShift);
10292 uint32_t TargetOrder = 0x0;
10299 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10300 TargetOrder = OriginalOrderLow;
10304 if (MaskOneElt == VINSERTHSrcElem &&
10305 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10306 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10307 FoundCandidate =
true;
10313 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10315 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10317 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10318 : BigEndianShifts[MaskOneElt & 0x7];
10319 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10320 Swap = MaskOneElt < NumHalfWords;
10321 FoundCandidate =
true;
10327 if (!FoundCandidate)
10344 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10349 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10362 auto ShuffleMask = SVN->
getMask();
10377 ShuffleMask = CommutedSV->
getMask();
10386 APInt APSplatValue, APSplatUndef;
10387 unsigned SplatBitSize;
10390 HasAnyUndefs, 0, !Subtarget.isLittleEndian()) ||
10402 bool IsLE = Subtarget.isLittleEndian();
10403 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10404 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10405 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10407 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10408 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10409 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10417 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10418 SplatVal |= (SplatVal << SplatBitSize);
10423 return DAG.
getNode(ISD::BITCAST,
DL, MVT::v16i8, SplatNode);
10432 assert(
Op.getValueType() == MVT::v1i128 &&
10433 "Only set v1i128 as custom, other type shouldn't reach here!");
10438 if (SHLAmt % 8 == 0) {
10439 std::array<int, 16>
Mask;
10440 std::iota(
Mask.begin(),
Mask.end(), 0);
10441 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10445 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, Shuffle);
10453 return DAG.
getNode(ISD::BITCAST, dl, MVT::v1i128, OROp);
10470 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10475 V1 =
Op.getOperand(0);
10476 V2 =
Op.getOperand(1);
10478 EVT VT =
Op.getValueType();
10479 bool isLittleEndian = Subtarget.isLittleEndian();
10481 unsigned ShiftElts, InsertAtByte;
10487 bool IsPermutedLoad =
false;
10489 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10499 if (IsPermutedLoad) {
10500 assert((isLittleEndian || IsFourByte) &&
10501 "Unexpected size for permuted load on big endian target");
10502 SplatIdx += IsFourByte ? 2 : 1;
10503 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10504 "Splat of a value outside of the loaded memory");
10509 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10512 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10514 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10518 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10531 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10534 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10543 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10546 if (Subtarget.hasP9Vector() &&
10560 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10564 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Ins);
10567 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10569 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10570 return SplatInsertNode;
10573 if (Subtarget.hasP9Altivec()) {
10575 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10578 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10582 if (Subtarget.hasVSX() &&
10588 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, V2.
isUndef() ? V1 : V2);
10592 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Shl);
10595 if (Subtarget.hasVSX() &&
10601 DAG.
getNode(ISD::BITCAST, dl, MVT::v2i64, V2.isUndef() ? V1 : V2);
10605 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, PermDI);
10608 if (Subtarget.hasP9Vector()) {
10612 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveHWord);
10616 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveWord);
10620 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveDWord);
10624 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, ReveQWord);
10628 if (Subtarget.hasVSX()) {
10635 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8,
Splat);
10642 return DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, Swap);
10649 if (V2.isUndef()) {
10662 (Subtarget.hasP8Altivec() && (
10673 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10683 (Subtarget.hasP8Altivec() && (
10691 ArrayRef<int> PermMask = SVOp->
getMask();
10694 unsigned PFIndexes[4];
10695 bool isFourElementShuffle =
true;
10696 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10698 unsigned EltNo = 8;
10699 for (
unsigned j = 0;
j != 4; ++
j) {
10700 if (PermMask[i * 4 + j] < 0)
10703 unsigned ByteSource = PermMask[i * 4 +
j];
10704 if ((ByteSource & 3) != j) {
10705 isFourElementShuffle =
false;
10710 EltNo = ByteSource / 4;
10711 }
else if (EltNo != ByteSource / 4) {
10712 isFourElementShuffle =
false;
10716 PFIndexes[i] = EltNo;
10724 if (isFourElementShuffle) {
10726 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10727 PFIndexes[2] * 9 + PFIndexes[3];
10730 unsigned Cost = (PFEntry >> 30);
10750 if (V2.isUndef()) V2 = V1;
10752 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10761 bool NeedSwap =
false;
10762 bool isLittleEndian = Subtarget.isLittleEndian();
10763 bool isPPC64 = Subtarget.isPPC64();
10765 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10767 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10768 "XXPERM instead\n");
10777 NeedSwap = !NeedSwap;
10812 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10814 if (V1HasXXSWAPD) {
10817 else if (SrcElt < 16)
10820 if (V2HasXXSWAPD) {
10823 else if (SrcElt > 15)
10832 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10833 if (isLittleEndian)
10835 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10838 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10841 if (V1HasXXSWAPD) {
10845 if (V2HasXXSWAPD) {
10850 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10851 if (ValType != MVT::v2f64)
10857 ShufflesHandledWithVPERM++;
10862 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10864 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10867 dbgs() <<
"With the following permute control vector:\n";
10872 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10876 if (isLittleEndian)
10882 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10894 switch (IntrinsicID) {
10898 case Intrinsic::ppc_altivec_vcmpbfp_p:
10902 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10906 case Intrinsic::ppc_altivec_vcmpequb_p:
10910 case Intrinsic::ppc_altivec_vcmpequh_p:
10914 case Intrinsic::ppc_altivec_vcmpequw_p:
10918 case Intrinsic::ppc_altivec_vcmpequd_p:
10919 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10925 case Intrinsic::ppc_altivec_vcmpneb_p:
10926 case Intrinsic::ppc_altivec_vcmpneh_p:
10927 case Intrinsic::ppc_altivec_vcmpnew_p:
10928 case Intrinsic::ppc_altivec_vcmpnezb_p:
10929 case Intrinsic::ppc_altivec_vcmpnezh_p:
10930 case Intrinsic::ppc_altivec_vcmpnezw_p:
10931 if (Subtarget.hasP9Altivec()) {
10932 switch (IntrinsicID) {
10935 case Intrinsic::ppc_altivec_vcmpneb_p:
10938 case Intrinsic::ppc_altivec_vcmpneh_p:
10941 case Intrinsic::ppc_altivec_vcmpnew_p:
10944 case Intrinsic::ppc_altivec_vcmpnezb_p:
10947 case Intrinsic::ppc_altivec_vcmpnezh_p:
10950 case Intrinsic::ppc_altivec_vcmpnezw_p:
10958 case Intrinsic::ppc_altivec_vcmpgefp_p:
10962 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10966 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10970 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10974 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10978 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10979 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10985 case Intrinsic::ppc_altivec_vcmpgtub_p:
10989 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10993 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10997 case Intrinsic::ppc_altivec_vcmpgtud_p:
10998 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
11005 case Intrinsic::ppc_altivec_vcmpequq:
11006 case Intrinsic::ppc_altivec_vcmpgtsq:
11007 case Intrinsic::ppc_altivec_vcmpgtuq:
11008 if (!Subtarget.isISA3_1())
11010 switch (IntrinsicID) {
11013 case Intrinsic::ppc_altivec_vcmpequq:
11016 case Intrinsic::ppc_altivec_vcmpgtsq:
11019 case Intrinsic::ppc_altivec_vcmpgtuq:
11026 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11027 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11028 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11029 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11030 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11031 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11032 if (Subtarget.hasVSX()) {
11033 switch (IntrinsicID) {
11034 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11037 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11040 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11043 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11046 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11049 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11059 case Intrinsic::ppc_altivec_vcmpbfp:
11062 case Intrinsic::ppc_altivec_vcmpeqfp:
11065 case Intrinsic::ppc_altivec_vcmpequb:
11068 case Intrinsic::ppc_altivec_vcmpequh:
11071 case Intrinsic::ppc_altivec_vcmpequw:
11074 case Intrinsic::ppc_altivec_vcmpequd:
11075 if (Subtarget.hasP8Altivec())
11080 case Intrinsic::ppc_altivec_vcmpneb:
11081 case Intrinsic::ppc_altivec_vcmpneh:
11082 case Intrinsic::ppc_altivec_vcmpnew:
11083 case Intrinsic::ppc_altivec_vcmpnezb:
11084 case Intrinsic::ppc_altivec_vcmpnezh:
11085 case Intrinsic::ppc_altivec_vcmpnezw:
11086 if (Subtarget.hasP9Altivec())
11087 switch (IntrinsicID) {
11090 case Intrinsic::ppc_altivec_vcmpneb:
11093 case Intrinsic::ppc_altivec_vcmpneh:
11096 case Intrinsic::ppc_altivec_vcmpnew:
11099 case Intrinsic::ppc_altivec_vcmpnezb:
11102 case Intrinsic::ppc_altivec_vcmpnezh:
11105 case Intrinsic::ppc_altivec_vcmpnezw:
11112 case Intrinsic::ppc_altivec_vcmpgefp:
11115 case Intrinsic::ppc_altivec_vcmpgtfp:
11118 case Intrinsic::ppc_altivec_vcmpgtsb:
11121 case Intrinsic::ppc_altivec_vcmpgtsh:
11124 case Intrinsic::ppc_altivec_vcmpgtsw:
11127 case Intrinsic::ppc_altivec_vcmpgtsd:
11128 if (Subtarget.hasP8Altivec())
11133 case Intrinsic::ppc_altivec_vcmpgtub:
11136 case Intrinsic::ppc_altivec_vcmpgtuh:
11139 case Intrinsic::ppc_altivec_vcmpgtuw:
11142 case Intrinsic::ppc_altivec_vcmpgtud:
11143 if (Subtarget.hasP8Altivec())
11148 case Intrinsic::ppc_altivec_vcmpequq_p:
11149 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11150 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11151 if (!Subtarget.isISA3_1())
11153 switch (IntrinsicID) {
11156 case Intrinsic::ppc_altivec_vcmpequq_p:
11159 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11162 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11176 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11180 switch (IntrinsicID) {
11181 case Intrinsic::thread_pointer:
11183 if (Subtarget.isPPC64())
11187 case Intrinsic::ppc_rldimi: {
11188 assert(Subtarget.isPPC64() &&
"rldimi is only available in 64-bit!");
11190 APInt
Mask =
Op.getConstantOperandAPInt(4);
11192 return Op.getOperand(2);
11193 if (
Mask.isAllOnes())
11195 uint64_t SH =
Op.getConstantOperandVal(3);
11196 unsigned MB = 0, ME = 0;
11200 if (ME < 63 - SH) {
11203 }
else if (ME > 63 - SH) {
11209 {Op.getOperand(2), Src,
11210 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11211 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11215 case Intrinsic::ppc_rlwimi: {
11216 APInt
Mask =
Op.getConstantOperandAPInt(4);
11218 return Op.getOperand(2);
11219 if (
Mask.isAllOnes())
11222 unsigned MB = 0, ME = 0;
11226 PPC::RLWIMI, dl, MVT::i32,
11227 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11228 DAG.getTargetConstant(MB, dl, MVT::i32),
11229 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11233 case Intrinsic::ppc_rlwnm: {
11234 if (
Op.getConstantOperandVal(3) == 0)
11236 unsigned MB = 0, ME = 0;
11241 {Op.getOperand(1), Op.getOperand(2),
11242 DAG.getTargetConstant(MB, dl, MVT::i32),
11243 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11247 case Intrinsic::ppc_mma_disassemble_acc: {
11248 if (Subtarget.isISAFuture()) {
11249 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11261 Subtarget.isLittleEndian() ? Value2 :
Value,
11262 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11267 Subtarget.isLittleEndian() ? Value2 :
Value,
11268 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11273 Subtarget.isLittleEndian() ?
Value : Value2,
11274 DAG.
getConstant(Subtarget.isLittleEndian() ? 1 : 0,
11279 Subtarget.isLittleEndian() ?
Value : Value2,
11280 DAG.
getConstant(Subtarget.isLittleEndian() ? 0 : 1,
11287 case Intrinsic::ppc_vsx_disassemble_pair: {
11290 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11295 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11298 DAG.
getConstant(Subtarget.isLittleEndian() ? NumVecs - 1 - VecNo
11306 case Intrinsic::ppc_mma_build_dmr: {
11309 for (
int i = 1; i < 9; i += 2) {
11312 if (
Hi->getOpcode() == ISD::LOAD)
11314 if (
Lo->getOpcode() == ISD::LOAD)
11324 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11325 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11327 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11328 "Specify P of 0 or 1 for lower or upper 512 bytes");
11329 unsigned HiLo = Idx->getSExtValue();
11333 Opcode = PPC::DMXXEXTFDMR512;
11334 Subx = PPC::sub_wacc_lo;
11336 Opcode = PPC::DMXXEXTFDMR512_HI;
11337 Subx = PPC::sub_wacc_hi;
11340 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11344 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11348 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11349 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11351 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11352 "Specify a dmr row pair 0-3");
11353 unsigned IdxVal = Idx->getSExtValue();
11357 Subx = PPC::sub_dmrrowp0;
11360 Subx = PPC::sub_dmrrowp1;
11363 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11366 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11370 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11376 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11380 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11381 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11383 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11384 "Specify P of 0 or 1 for lower or upper 512 bytes");
11385 unsigned HiLo = Idx->getSExtValue();
11389 Opcode = PPC::DMXXINSTDMR512;
11390 Subx = PPC::sub_wacc_lo;
11392 Opcode = PPC::DMXXINSTDMR512_HI;
11393 Subx = PPC::sub_wacc_hi;
11403 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11404 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11406 assert(Idx && (Idx->getSExtValue() >= 0 || Idx->getSExtValue() <= 3) &&
11407 "Specify a dmr row pair 0-3");
11408 unsigned IdxVal = Idx->getSExtValue();
11412 Subx = PPC::sub_dmrrowp0;
11415 Subx = PPC::sub_dmrrowp1;
11418 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11421 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11430 Op.getOperand(1), DMRRowp,
SubReg),
11434 case Intrinsic::ppc_mma_xxmfacc:
11435 case Intrinsic::ppc_mma_xxmtacc: {
11437 if (!Subtarget.isISAFuture())
11448 case Intrinsic::ppc_unpack_longdouble: {
11450 assert(Idx && (Idx->getSExtValue() == 0 || Idx->getSExtValue() == 1) &&
11451 "Argument of long double unpack must be 0 or 1!");
11454 Idx->getValueType(0)));
11457 case Intrinsic::ppc_compare_exp_lt:
11458 case Intrinsic::ppc_compare_exp_gt:
11459 case Intrinsic::ppc_compare_exp_eq:
11460 case Intrinsic::ppc_compare_exp_uo: {
11462 switch (IntrinsicID) {
11463 case Intrinsic::ppc_compare_exp_lt:
11466 case Intrinsic::ppc_compare_exp_gt:
11469 case Intrinsic::ppc_compare_exp_eq:
11472 case Intrinsic::ppc_compare_exp_uo:
11478 PPC::SELECT_CC_I4, dl, MVT::i32,
11479 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11480 Op.getOperand(1), Op.getOperand(2)),
11482 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11483 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11486 case Intrinsic::ppc_test_data_class: {
11487 EVT OpVT =
Op.getOperand(1).getValueType();
11488 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11489 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11493 PPC::SELECT_CC_I4, dl, MVT::i32,
11494 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11497 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11498 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11501 case Intrinsic::ppc_fnmsub: {
11502 EVT VT =
Op.getOperand(1).getValueType();
11503 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11507 DAG.
getNode(ISD::FNEG, dl, VT,
Op.getOperand(3))));
11509 Op.getOperand(2),
Op.getOperand(3));
11511 case Intrinsic::ppc_convert_f128_to_ppcf128:
11512 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11513 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11514 ? RTLIB::CONVERT_PPCF128_F128
11515 : RTLIB::CONVERT_F128_PPCF128;
11517 std::pair<SDValue, SDValue>
Result =
11518 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11522 case Intrinsic::ppc_maxfe:
11523 case Intrinsic::ppc_maxfl:
11524 case Intrinsic::ppc_maxfs:
11525 case Intrinsic::ppc_minfe:
11526 case Intrinsic::ppc_minfl:
11527 case Intrinsic::ppc_minfs: {
11528 EVT VT =
Op.getValueType();
11531 [VT](
const SDUse &Use) { return Use.getValueType() == VT; }) &&
11532 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11535 if (IntrinsicID == Intrinsic::ppc_minfe ||
11536 IntrinsicID == Intrinsic::ppc_minfl ||
11537 IntrinsicID == Intrinsic::ppc_minfs)
11559 Op.getOperand(1),
Op.getOperand(2),
11561 return DAG.
getNode(ISD::BITCAST, dl,
Op.getValueType(), Tmp);
11570 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11578 switch (
Op.getConstantOperandVal(1)) {
11583 Bitx = PPC::sub_eq;
11589 Bitx = PPC::sub_eq;
11595 Bitx = PPC::sub_lt;
11601 Bitx = PPC::sub_lt;
11607 if (Subtarget.isISA3_1()) {
11612 CR6Reg, SubRegIdx, GlueOp),
11614 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11642 switch (
Op.getConstantOperandVal(ArgStart)) {
11643 case Intrinsic::ppc_cfence: {
11644 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11645 SDValue Val =
Op.getOperand(ArgStart + 1);
11647 if (Ty == MVT::i128) {
11652 unsigned Opcode = Subtarget.isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11655 Opcode,
DL, MVT::Other,
11660 case Intrinsic::ppc_mma_disassemble_dmr: {
11662 Op.getOperand(ArgStart + 1), MachinePointerInfo());
11673 if (!Subtarget.isPPC64())
11681 int VectorIndex = 0;
11682 if (Subtarget.isLittleEndian())
11693 assert(
Op.getOpcode() == ISD::ATOMIC_CMP_SWAP &&
11694 "Expecting an atomic compare-and-swap here.");
11697 EVT MemVT = AtomicNode->getMemoryVT();
11715 for (
int i = 0, e = AtomicNode->getNumOperands(); i < e; i++)
11716 Ops.push_back(AtomicNode->getOperand(i));
11718 MachineMemOperand *MMO = AtomicNode->getMemOperand();
11719 SDVTList Tys = DAG.
getVTList(MVT::i32, MVT::Other);
11728 EVT MemVT =
N->getMemoryVT();
11730 "Expect quadword atomic operations");
11732 unsigned Opc =
N->getOpcode();
11734 case ISD::ATOMIC_LOAD: {
11737 SDVTList Tys = DAG.
getVTList(MVT::i64, MVT::i64, MVT::Other);
11740 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11741 for (
int I = 1,
E =
N->getNumOperands();
I <
E; ++
I)
11742 Ops.push_back(
N->getOperand(
I));
11744 Ops, MemVT,
N->getMemOperand());
11751 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11755 case ISD::ATOMIC_STORE: {
11758 SDVTList Tys = DAG.
getVTList(MVT::Other);
11761 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11767 Ops.push_back(ValLo);
11768 Ops.push_back(ValHi);
11769 Ops.push_back(
N->getOperand(2));
11771 N->getMemOperand());
11783 enum DataClassMask {
11785 DC_NEG_INF = 1 << 4,
11786 DC_POS_INF = 1 << 5,
11787 DC_NEG_ZERO = 1 << 2,
11788 DC_POS_ZERO = 1 << 3,
11789 DC_NEG_SUBNORM = 1,
11790 DC_POS_SUBNORM = 1 << 1,
11793 EVT VT =
Op.getValueType();
11795 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11796 : VT == MVT::f64 ? PPC::XSTSTDCDP
11807 return DAG.
getNOT(Dl, Rev, MVT::i1);
11814 TestOp, Dl, MVT::i32,
11816 DC_NEG_ZERO | DC_POS_ZERO |
11817 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11823 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11829 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11834 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11847 bool IsQuiet = Mask &
fcQNan;
11853 if (VT == MVT::f128) {
11857 QuietMask = 0x8000;
11858 }
else if (VT == MVT::f64) {
11859 if (Subtarget.isPPC64()) {
11870 QuietMask = 0x80000;
11871 }
else if (VT == MVT::f32) {
11873 QuietMask = 0x400000;
11889 unsigned NativeMask = 0;
11891 NativeMask |= DC_NAN;
11893 NativeMask |= DC_NEG_INF;
11895 NativeMask |= DC_POS_INF;
11897 NativeMask |= DC_NEG_ZERO;
11899 NativeMask |= DC_POS_ZERO;
11901 NativeMask |= DC_NEG_SUBNORM;
11903 NativeMask |= DC_POS_SUBNORM;
11906 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11908 TestOp, Dl, MVT::i32,
11917 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11919 uint64_t RHSC =
Op.getConstantOperandVal(1);
11922 if (
LHS.getValueType() == MVT::ppcf128) {
11946 bool Future = Subtarget.isISAFuture();
11949 "Mask predication not supported");
11952 unsigned IID = Future ? Intrinsic::ppc_vsx_lxvrl : Intrinsic::ppc_vsx_lxvl;
11953 unsigned EltBits =
Op->getValueType(0).getScalarType().getSizeInBits();
11957 SDVTList Tys = DAG.
getVTList(
Op->getValueType(0), MVT::Other);
11960 VPLD->getMemoryVT(), VPLD->getMemOperand());
11967 "Mask predication not supported");
11972 Op->getOperand(1).getValueType().getScalarType().getSizeInBits();
11973 bool Future = Subtarget.isISAFuture();
11974 unsigned IID = Future ? Intrinsic::ppc_vsx_stxvrl : Intrinsic::ppc_vsx_stxvl;
11977 VPST->getChain(), DAG.
getConstant(IID, dl, MVT::i32),
11978 DAG.
getNode(ISD::BITCAST, dl, MVT::v4i32, VPST->getOperand(1)),
11980 SDVTList Tys = DAG.
getVTList(MVT::Other);
11983 VPST->getMemoryVT(), VPST->getMemOperand());
11994 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11996 int64_t
IntVal =
Op.getConstantOperandVal(0);
11997 if (IntVal >= -16 && IntVal <= 15)
12003 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
12004 Op.getValueType() == MVT::v4i32 && Op0.
getOpcode() == ISD::LOAD &&
12008 MachineMemOperand *MMO =
12010 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
12017 return Bits.getValue(0);
12033 !Subtarget.isLittleEndian() && ValVT.
isInteger() &&
12038 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
12045 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
12046 MachinePointerInfo());
12053 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx, MachinePointerInfo());
12059 "Should only be called for ISD::INSERT_VECTOR_ELT");
12063 EVT VT =
Op.getValueType();
12068 if (VT == MVT::v2f64 &&
C)
12071 if (Subtarget.hasP9Vector()) {
12080 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
12086 BitcastLoad,
Op.getOperand(2));
12087 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12091 if (Subtarget.isISA3_1()) {
12092 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.isPPC64())
12096 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12097 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12107 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12110 unsigned InsertAtElement =
C->getZExtValue();
12111 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12112 if (Subtarget.isLittleEndian()) {
12113 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12127 EVT VT =
Op.getValueType();
12128 bool IsV1024i1 = VT == MVT::v1024i1;
12129 bool IsV2048i1 = VT == MVT::v2048i1;
12133 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12135 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12136 "Dense Math support required.");
12137 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12146 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12147 MachineMemOperand *NewMMO =
12155 DAG.
getVTList(MVT::v256i1, MVT::Other),
12156 LoadOps, MVT::v256i1, NewMMO);
12161 if (Subtarget.isLittleEndian()) {
12162 std::reverse(Loads.
begin(), Loads.
end());
12163 std::reverse(LoadChains.
begin(), LoadChains.
end());
12172 Loads[2], Loads[3]),
12188 Loads[4], Loads[5]),
12191 Loads[6], Loads[7]),
12193 const SDValue Dmr1Ops[] = {RC, Dmr1Lo, LoSub, Dmr1Hi, HiSub};
12195 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Dmr1Ops), 0);
12201 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12204 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12217 Pairs[2], Pairs[3]),
12223 {RC, Lo, LoSub, Hi, HiSub}),
12233 EVT VT =
Op.getValueType();
12235 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12236 return LowerDMFVectorLoad(
Op, DAG);
12238 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12244 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12245 "Type unsupported without MMA");
12246 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12247 "Type unsupported without paired vector support");
12252 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12254 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12263 if (Subtarget.isLittleEndian()) {
12264 std::reverse(Loads.
begin(), Loads.
end());
12265 std::reverse(LoadChains.
begin(), LoadChains.
end());
12285 bool IsV1024i1 = VT == MVT::v1024i1;
12286 bool IsV2048i1 = VT == MVT::v2048i1;
12290 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12292 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12293 "Dense Math support required.");
12294 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12296 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12299 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12304 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12308 MachineSDNode *ExtNode =
12312 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12318 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12324 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12330 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12335 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12340 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12345 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12349 MachineSDNode *ExtNode =
12350 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12354 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12357 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12361 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12366 if (Subtarget.isLittleEndian())
12367 std::reverse(Values.
begin(), Values.
end());
12369 SDVTList Tys = DAG.
getVTList(MVT::Other);
12371 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12375 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12376 MachineMemOperand *NewMMO =
12383 Ops[2] = Values[Idx];
12385 MVT::v256i1, NewMMO);
12401 EVT StoreVT =
Value.getValueType();
12403 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12404 return LowerDMFVectorStore(
Op, DAG);
12406 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12412 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12413 "Type unsupported without MMA");
12414 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12415 "Type unsupported without paired vector support");
12418 unsigned NumVecs = 2;
12419 if (StoreVT == MVT::v512i1) {
12420 if (Subtarget.isISAFuture()) {
12421 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12423 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12426 Value2 =
SDValue(ExtNode, 1);
12431 for (
unsigned Idx = 0; Idx < NumVecs; ++Idx) {
12432 unsigned VecNum = Subtarget.isLittleEndian() ? NumVecs - 1 - Idx : Idx;
12434 if (Subtarget.isISAFuture()) {
12435 VecNum = Subtarget.isLittleEndian() ? 1 - (Idx % 2) : (Idx % 2);
12437 Idx > 1 ? Value2 :
Value,
12444 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12458 if (
Op.getValueType() == MVT::v4i32) {
12470 RHSSwap = DAG.
getNode(ISD::BITCAST, dl, MVT::v8i16, RHSSwap);
12475 LHS,
RHS, DAG, dl, MVT::v4i32);
12478 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12483 }
else if (
Op.getValueType() == MVT::v16i8) {
12485 bool isLittleEndian = Subtarget.isLittleEndian();
12489 LHS,
RHS, DAG, dl, MVT::v8i16);
12490 EvenParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, EvenParts);
12494 LHS,
RHS, DAG, dl, MVT::v8i16);
12495 OddParts = DAG.
getNode(ISD::BITCAST, dl, MVT::v16i8, OddParts);
12502 for (
unsigned i = 0; i != 8; ++i) {
12503 if (isLittleEndian) {
12505 Ops[i*2+1] = 2*i+16;
12508 Ops[i*2+1] = 2*i+1+16;
12511 if (isLittleEndian)
12521 bool IsStrict =
Op->isStrictFPOpcode();
12522 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12523 !Subtarget.hasP9Vector())
12532 assert(
Op.getOpcode() == ISD::FP_EXTEND &&
12533 "Should only be called for ISD::FP_EXTEND");
12537 if (
Op.getValueType() != MVT::v2f64 ||
12538 Op.getOperand(0).getValueType() != MVT::v2f32)
12550 "Node should have 2 operands with second one being a constant!");
12562 int DWord = Idx >> 1;
12565 if (Subtarget.isLittleEndian())
12582 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12585 LD->getMemoryVT(),
LD->getMemOperand());
12595 SDValue LoadOps[] = {
LD->getChain(),
LD->getBasePtr()};
12598 LD->getMemoryVT(),
LD->getMemOperand());
12610 if (STI.useCRBits())
12628 if (STI.useCRBits())
12636 SDNode *
N =
Op.getNode();
12637 EVT VT =
N->getValueType(0);
12638 EVT CarryType =
N->getValueType(1);
12639 unsigned Opc =
N->getOpcode();
12643 N->getOperand(0),
N->getOperand(1));
12655 SDNode *
N =
Op.getNode();
12656 unsigned Opc =
N->getOpcode();
12657 EVT VT =
N->getValueType(0);
12658 EVT CarryType =
N->getValueType(1);
12659 SDValue CarryOp =
N->getOperand(2);
12667 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12681 EVT VT =
Op.getNode()->getValueType(0);
12705 EVT OpVT =
A.getValueType();
12706 EVT ResVT =
Op.getValueType();
12712 SDVTList VTs = DAG.
getVTList(OpVT, MVT::i32);
12730 switch (
Op.getOpcode()) {
12733 case ISD::FPOW:
return lowerPow(
Op, DAG);
12734 case ISD::FSIN:
return lowerSin(
Op, DAG);
12735 case ISD::FCOS:
return lowerCos(
Op, DAG);
12736 case ISD::FLOG:
return lowerLog(
Op, DAG);
12737 case ISD::FLOG10:
return lowerLog10(
Op, DAG);
12738 case ISD::FEXP:
return lowerExp(
Op, DAG);
12747 case ISD::INIT_TRAMPOLINE:
return LowerINIT_TRAMPOLINE(
Op, DAG);
12748 case ISD::ADJUST_TRAMPOLINE:
return LowerADJUST_TRAMPOLINE(
Op, DAG);
12750 return LowerSSUBO(
Op, DAG);
12752 case ISD::INLINEASM:
12753 case ISD::INLINEASM_BR:
return LowerINLINEASM(
Op, DAG);
12755 case ISD::VASTART:
return LowerVASTART(
Op, DAG);
12756 case ISD::VAARG:
return LowerVAARG(
Op, DAG);
12757 case ISD::VACOPY:
return LowerVACOPY(
Op, DAG);
12759 case ISD::STACKRESTORE:
return LowerSTACKRESTORE(
Op, DAG);
12760 case ISD::DYNAMIC_STACKALLOC:
return LowerDYNAMIC_STACKALLOC(
Op, DAG);
12761 case ISD::GET_DYNAMIC_AREA_OFFSET:
12762 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12769 case ISD::LOAD:
return LowerLOAD(
Op, DAG);
12770 case ISD::STORE:
return LowerSTORE(
Op, DAG);
12782 case ISD::SET_ROUNDING:
12783 return LowerSET_ROUNDING(
Op, DAG);
12790 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12791 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12800 case ISD::FP_EXTEND:
return LowerFP_EXTEND(
Op, DAG);
12803 return LowerFP_ROUND(
Op, DAG);
12809 case ISD::BITCAST:
return LowerBITCAST(
Op, DAG);
12816 return LowerINTRINSIC_VOID(
Op, DAG);
12818 return LowerBSWAP(
Op, DAG);
12819 case ISD::ATOMIC_CMP_SWAP:
12820 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12821 case ISD::ATOMIC_STORE:
12822 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12824 return LowerIS_FPCLASS(
Op, DAG);
12827 return LowerADDSUBO(
Op, DAG);
12830 return LowerADDSUBO_CARRY(
Op, DAG);
12832 return LowerUCMP(
Op, DAG);
12838 if (
Op->getFlags().hasNoFPExcept())
12842 return LowerVP_LOAD(
Op, DAG);
12843 case ISD::VP_STORE:
12844 return LowerVP_STORE(
Op, DAG);
12852 switch (
N->getOpcode()) {
12854 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12855 case ISD::ATOMIC_LOAD: {
12861 case ISD::READCYCLECOUNTER: {
12871 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12874 assert(
N->getValueType(0) == MVT::i1 &&
12875 "Unexpected result type for CTR decrement intrinsic");
12877 N->getValueType(0));
12887 switch (
N->getConstantOperandVal(0)) {
12888 case Intrinsic::ppc_pack_longdouble:
12890 N->getOperand(2),
N->getOperand(1)));
12892 case Intrinsic::ppc_maxfe:
12893 case Intrinsic::ppc_minfe:
12894 case Intrinsic::ppc_fnmsub:
12895 case Intrinsic::ppc_convert_f128_to_ppcf128:
12902 if (!Subtarget.isSVR4ABI() || Subtarget.isPPC64())
12905 EVT VT =
N->getValueType(0);
12907 if (VT == MVT::i64) {
12920 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12924 Results.push_back(LoweredValue);
12925 if (
N->isStrictFPOpcode())
12930 if (!
N->getValueType(0).isVector())
12950 case ISD::FP_EXTEND:
12963 return Builder.CreateIntrinsic(Id, {});
12969 unsigned SZ = ValueTy->getPrimitiveSizeInBits();
12971 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12972 "Only 8/16/32/64-bit atomic loads supported");
12978 IntID = Intrinsic::ppc_lbarx;
12979 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12982 IntID = Intrinsic::ppc_lharx;
12983 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12986 IntID = Intrinsic::ppc_lwarx;
12989 IntID = Intrinsic::ppc_ldarx;
12993 Builder.CreateIntrinsic(IntID, Addr,
nullptr,
"larx");
12995 return Builder.CreateTruncOrBitCast(
Call, ValueTy);
13006 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
13007 "Only 8/16/32/64-bit atomic loads supported");
13013 IntID = Intrinsic::ppc_stbcx;
13014 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13017 IntID = Intrinsic::ppc_sthcx;
13018 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13021 IntID = Intrinsic::ppc_stwcx;
13024 IntID = Intrinsic::ppc_stdcx;
13028 if (SZ == 8 || SZ == 16)
13029 Val = Builder.CreateZExt(Val, Builder.getInt32Ty());
13031 Value *
Call = Builder.CreateIntrinsic(IntID, {Addr, Val},
13033 return Builder.CreateXor(
Call, Builder.getInt32(1));
13056 return Builder.CreateIntrinsic(Intrinsic::ppc_cfence, {Inst->
getType()},
13066 unsigned AtomicSize,
13067 unsigned BinOpcode,
13068 unsigned CmpOpcode,
13069 unsigned CmpPred)
const {
13073 auto LoadMnemonic = PPC::LDARX;
13074 auto StoreMnemonic = PPC::STDCX;
13075 switch (AtomicSize) {
13079 LoadMnemonic = PPC::LBARX;
13080 StoreMnemonic = PPC::STBCX;
13081 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13084 LoadMnemonic = PPC::LHARX;
13085 StoreMnemonic = PPC::STHCX;
13086 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
13089 LoadMnemonic = PPC::LWARX;
13090 StoreMnemonic = PPC::STWCX;
13093 LoadMnemonic = PPC::LDARX;
13094 StoreMnemonic = PPC::STDCX;
13110 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13112 F->insert(It, loopMBB);
13114 F->insert(It, loop2MBB);
13115 F->insert(It, exitMBB);
13121 Register TmpReg = (!BinOpcode) ? incr :
13122 RegInfo.createVirtualRegister( AtomicSize == 8 ? &PPC::G8RCRegClass
13123 : &PPC::GPRCRegClass);
13148 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13153 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13155 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13156 Register ExtReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13157 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13187 switch(
MI.getOpcode()) {
13191 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13192 &
MI.getMF()->getRegInfo());
13216 case PPC::EXTSB8_32_64:
13217 case PPC::EXTSB8_rec:
13218 case PPC::EXTSB_rec:
13221 case PPC::EXTSH8_32_64:
13222 case PPC::EXTSH8_rec:
13223 case PPC::EXTSH_rec:
13225 case PPC::EXTSWSLI:
13226 case PPC::EXTSWSLI_32_64:
13227 case PPC::EXTSWSLI_32_64_rec:
13228 case PPC::EXTSWSLI_rec:
13229 case PPC::EXTSW_32:
13230 case PPC::EXTSW_32_64:
13231 case PPC::EXTSW_32_64_rec:
13232 case PPC::EXTSW_rec:
13235 case PPC::SRAWI_rec:
13236 case PPC::SRAW_rec:
13245 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13255 bool IsSignExtended =
13258 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13259 Register ValueReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
13260 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13261 .
addReg(
MI.getOperand(3).getReg());
13262 MI.getOperand(3).setReg(ValueReg);
13266 if (Subtarget.hasPartwordAtomics())
13274 bool is64bit = Subtarget.isPPC64();
13275 bool isLittleEndian = Subtarget.isLittleEndian();
13276 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13287 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13289 F->insert(It, loopMBB);
13291 F->insert(It, loop2MBB);
13292 F->insert(It, exitMBB);
13298 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13301 Register PtrReg = RegInfo.createVirtualRegister(RC);
13302 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
13304 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
13305 Register Incr2Reg = RegInfo.createVirtualRegister(GPRC);
13306 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
13307 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
13308 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
13309 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
13310 Register Tmp3Reg = RegInfo.createVirtualRegister(GPRC);
13311 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
13312 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
13313 Register SrwDestReg = RegInfo.createVirtualRegister(GPRC);
13316 (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC);
13343 if (ptrA != ZeroReg) {
13344 Ptr1Reg = RegInfo.createVirtualRegister(RC);
13345 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13353 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13354 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13357 .
addImm(is8bit ? 28 : 27);
13358 if (!isLittleEndian)
13359 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13361 .
addImm(is8bit ? 24 : 16);
13363 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13368 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13378 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13382 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13387 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13391 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13394 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13401 Register SReg = RegInfo.createVirtualRegister(GPRC);
13402 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
13406 unsigned ValueReg = SReg;
13407 unsigned CmpReg = Incr2Reg;
13408 if (CmpOpcode == PPC::CMPW) {
13409 ValueReg = RegInfo.createVirtualRegister(GPRC);
13410 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13413 Register ValueSReg = RegInfo.createVirtualRegister(GPRC);
13414 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13416 ValueReg = ValueSReg;
13448 .
addImm(is8bit ? 24 : 16)
13469 Register DstReg =
MI.getOperand(0).getReg();
13471 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13472 Register mainDstReg =
MRI.createVirtualRegister(RC);
13473 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13476 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13477 "Invalid Pointer Size!");
13525 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13526 Register BufReg =
MI.getOperand(1).getReg();
13528 if (Subtarget.is64BitELFABI()) {
13541 BaseReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;
13543 BaseReg = Subtarget.isPPC64() ? PPC::BP8 : PPC::BP;
13546 TII->get(Subtarget.isPPC64() ? PPC::STD : PPC::STW))
13569 TII->get(Subtarget.isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13572 if (Subtarget.isPPC64()) {
13590 TII->get(PPC::PHI), DstReg)
13594 MI.eraseFromParent();
13608 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13609 "Invalid Pointer Size!");
13612 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13615 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13616 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13630 Register BufReg =
MI.getOperand(0).getReg();
13635 if (PVT == MVT::i64) {
13647 if (PVT == MVT::i64) {
13659 if (PVT == MVT::i64) {
13671 if (PVT == MVT::i64) {
13683 if (PVT == MVT::i64 && Subtarget.isSVR4ABI()) {
13693 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13696 MI.eraseFromParent();
13712 "Unexpected stack alignment");
13716 unsigned StackProbeSize =
13719 StackProbeSize &= ~(StackAlign - 1);
13720 return StackProbeSize ? StackProbeSize : StackAlign;
13732 const bool isPPC64 = Subtarget.isPPC64();
13764 MF->
insert(MBBIter, TestMBB);
13765 MF->
insert(MBBIter, BlockMBB);
13766 MF->
insert(MBBIter, TailMBB);
13771 Register DstReg =
MI.getOperand(0).getReg();
13772 Register NegSizeReg =
MI.getOperand(1).getReg();
13774 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13775 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13776 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13782 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13784 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13790 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13791 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13793 .
addDef(ActualNegSizeReg)
13795 .
add(
MI.getOperand(2))
13796 .
add(
MI.getOperand(3));
13802 .
addReg(ActualNegSizeReg);
13805 int64_t NegProbeSize = -(int64_t)ProbeSize;
13807 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13809 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13811 .
addImm(NegProbeSize >> 16);
13815 .
addImm(NegProbeSize & 0xFFFF);
13822 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13824 .
addReg(ActualNegSizeReg)
13826 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13830 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13833 .
addReg(ActualNegSizeReg);
13842 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13843 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13868 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13870 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13871 MaxCallFrameSizeReg)
13872 .
add(
MI.getOperand(2))
13873 .
add(
MI.getOperand(3));
13874 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13876 .
addReg(MaxCallFrameSizeReg);
13882 MBB->addSuccessor(TestMBB);
13885 MI.eraseFromParent();
13887 ++NumDynamicAllocaProbed;
13892 switch (
MI.getOpcode()) {
13893 case PPC::SELECT_CC_I4:
13894 case PPC::SELECT_CC_I8:
13895 case PPC::SELECT_CC_F4:
13896 case PPC::SELECT_CC_F8:
13897 case PPC::SELECT_CC_F16:
13898 case PPC::SELECT_CC_VRRC:
13899 case PPC::SELECT_CC_VSFRC:
13900 case PPC::SELECT_CC_VSSRC:
13901 case PPC::SELECT_CC_VSRC:
13902 case PPC::SELECT_CC_SPE4:
13903 case PPC::SELECT_CC_SPE:
13911 switch (
MI.getOpcode()) {
13912 case PPC::SELECT_I4:
13913 case PPC::SELECT_I8:
13914 case PPC::SELECT_F4:
13915 case PPC::SELECT_F8:
13916 case PPC::SELECT_F16:
13917 case PPC::SELECT_SPE:
13918 case PPC::SELECT_SPE4:
13919 case PPC::SELECT_VRRC:
13920 case PPC::SELECT_VSFRC:
13921 case PPC::SELECT_VSSRC:
13922 case PPC::SELECT_VSRC:
13932 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13933 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13934 if (Subtarget.is64BitELFABI() &&
13935 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13936 !Subtarget.isUsingPCRelativeCalls()) {
13948 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13949 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13951 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13952 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13966 if (Subtarget.hasISEL() &&
13967 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13968 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13969 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13971 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13972 MI.getOpcode() == PPC::SELECT_CC_I8)
13973 Cond.push_back(
MI.getOperand(4));
13976 Cond.push_back(
MI.getOperand(1));
13979 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13980 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13996 F->insert(It, copy0MBB);
13997 F->insert(It, sinkMBB);
14006 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
14021 .
addReg(
MI.getOperand(1).getReg())
14024 unsigned SelectPred =
MI.getOperand(4).getImm();
14027 .
addReg(
MI.getOperand(1).getReg())
14044 .
addReg(
MI.getOperand(3).getReg())
14046 .
addReg(
MI.getOperand(2).getReg())
14048 }
else if (
MI.getOpcode() == PPC::ReadTB) {
14064 F->insert(It, readMBB);
14065 F->insert(It, sinkMBB);
14076 Register ReadAgainReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass);
14084 Register CmpReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14086 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
14096 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
14098 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
14100 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
14102 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
14105 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
14107 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
14109 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
14111 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
14114 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
14116 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
14118 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
14120 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
14123 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
14125 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
14127 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14129 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14132 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14134 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14136 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14138 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14141 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14143 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14145 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14147 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14150 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14152 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14154 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14156 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14159 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14161 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14163 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14165 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14168 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14170 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14172 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14174 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14177 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14179 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14181 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14183 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14186 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14188 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14190 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14192 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14194 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14195 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14196 (Subtarget.hasPartwordAtomics() &&
14197 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14198 (Subtarget.hasPartwordAtomics() &&
14199 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14200 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14202 auto LoadMnemonic = PPC::LDARX;
14203 auto StoreMnemonic = PPC::STDCX;
14204 switch (
MI.getOpcode()) {
14207 case PPC::ATOMIC_CMP_SWAP_I8:
14208 LoadMnemonic = PPC::LBARX;
14209 StoreMnemonic = PPC::STBCX;
14210 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14212 case PPC::ATOMIC_CMP_SWAP_I16:
14213 LoadMnemonic = PPC::LHARX;
14214 StoreMnemonic = PPC::STHCX;
14215 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14217 case PPC::ATOMIC_CMP_SWAP_I32:
14218 LoadMnemonic = PPC::LWARX;
14219 StoreMnemonic = PPC::STWCX;
14221 case PPC::ATOMIC_CMP_SWAP_I64:
14222 LoadMnemonic = PPC::LDARX;
14223 StoreMnemonic = PPC::STDCX;
14230 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14231 Register oldval =
MI.getOperand(3).getReg();
14232 Register newval =
MI.getOperand(4).getReg();
14238 F->insert(It, loop1MBB);
14239 F->insert(It, loop2MBB);
14240 F->insert(It, exitMBB);
14261 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14287 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14288 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14292 bool is64bit = Subtarget.isPPC64();
14293 bool isLittleEndian = Subtarget.isLittleEndian();
14294 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14299 Register oldval =
MI.getOperand(3).getReg();
14300 Register newval =
MI.getOperand(4).getReg();
14306 F->insert(It, loop1MBB);
14307 F->insert(It, loop2MBB);
14308 F->insert(It, exitMBB);
14315 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14318 Register PtrReg = RegInfo.createVirtualRegister(RC);
14319 Register Shift1Reg = RegInfo.createVirtualRegister(GPRC);
14321 isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC);
14322 Register NewVal2Reg = RegInfo.createVirtualRegister(GPRC);
14323 Register NewVal3Reg = RegInfo.createVirtualRegister(GPRC);
14324 Register OldVal2Reg = RegInfo.createVirtualRegister(GPRC);
14325 Register OldVal3Reg = RegInfo.createVirtualRegister(GPRC);
14326 Register MaskReg = RegInfo.createVirtualRegister(GPRC);
14327 Register Mask2Reg = RegInfo.createVirtualRegister(GPRC);
14328 Register Mask3Reg = RegInfo.createVirtualRegister(GPRC);
14329 Register Tmp2Reg = RegInfo.createVirtualRegister(GPRC);
14330 Register Tmp4Reg = RegInfo.createVirtualRegister(GPRC);
14331 Register TmpDestReg = RegInfo.createVirtualRegister(GPRC);
14333 Register TmpReg = RegInfo.createVirtualRegister(GPRC);
14334 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14335 Register CrReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14366 if (ptrA != ZeroReg) {
14367 Ptr1Reg = RegInfo.createVirtualRegister(RC);
14368 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14377 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14378 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
14381 .
addImm(is8bit ? 28 : 27);
14382 if (!isLittleEndian)
14383 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14385 .
addImm(is8bit ? 24 : 16);
14387 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14392 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14397 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14400 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14407 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14411 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14414 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14417 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14422 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14439 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14463 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14473 Register MFFSReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14488 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14496 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14497 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14498 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14499 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14500 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14501 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14504 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14505 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14508 Register Dest = RegInfo.createVirtualRegister(
14509 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14513 .
addReg(
MI.getOperand(1).getReg())
14516 MI.getOperand(0).getReg())
14517 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14518 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14521 Register CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass);
14524 MI.getOperand(0).getReg())
14526 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14528 unsigned Imm =
MI.getOperand(1).getImm();
14531 MI.getOperand(0).getReg())
14533 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14535 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14538 if (
MRI.use_empty(OldFPSCRReg))
14539 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14541 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14552 unsigned Mode =
MI.getOperand(1).getImm();
14553 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14557 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14560 }
else if (
MI.getOpcode() == PPC::SETRND) {
14568 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14569 if (Subtarget.hasDirectMove()) {
14570 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14574 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14577 if (RC == &PPC::F8RCRegClass) {
14579 assert((RegInfo.getRegClass(DestReg) == &PPC::G8RCRegClass) &&
14580 "Unsupported RegClass.");
14582 StoreOp = PPC::STFD;
14586 assert((RegInfo.getRegClass(SrcReg) == &PPC::G8RCRegClass) &&
14587 (RegInfo.getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14588 "Unsupported RegClass.");
14621 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14624 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14636 Register OldFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14638 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14640 Register ImDefReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14641 Register ExtSrcReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14646 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14647 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14652 Register NewFPSCRTmpReg = RegInfo.createVirtualRegister(&PPC::G8RCRegClass);
14653 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14659 Register NewFPSCRReg = RegInfo.createVirtualRegister(&PPC::F8RCRegClass);
14660 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14669 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14673 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14674 if (
MRI.use_empty(OldFPSCRReg))
14675 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14677 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14680 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14686 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14687 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14689 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14696 .
addUse(Src, 0, PPC::sub_gp8_x1);
14699 .
addUse(Src, 0, PPC::sub_gp8_x0);
14700 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14701 MI.getOpcode() == PPC::STQX_PSEUDO) {
14707 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14713 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14714 :
TII->get(PPC::STQ))
14722 MI.eraseFromParent();
14735 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14738 return RefinementSteps;
14744 EVT VT =
Op.getValueType();
14747 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14771PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14774 EVT VT =
Op.getValueType();
14775 if (VT != MVT::f64 &&
14776 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14783 int Enabled,
int &RefinementSteps,
14784 bool &UseOneConstNR,
14785 bool Reciprocal)
const {
14787 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14788 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14789 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14790 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14796 UseOneConstNR = !Subtarget.needsTwoConstNR();
14804 int &RefinementSteps)
const {
14806 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14807 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14808 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14809 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14828 switch (Subtarget.getCPUDirective()) {
14855 unsigned Bytes,
int Dist,
14869 if (FS != BFS || FS != (
int)Bytes)
return false;
14874 int64_t Offset1 = 0, Offset2 = 0;
14877 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14887 if (isGA1 && isGA2 && GV1 == GV2)
14888 return Offset1 == (Offset2 + Dist*Bytes);
14895 unsigned Bytes,
int Dist,
14898 EVT VT = LS->getMemoryVT();
14905 switch (
N->getConstantOperandVal(1)) {
14906 default:
return false;
14907 case Intrinsic::ppc_altivec_lvx:
14908 case Intrinsic::ppc_altivec_lvxl:
14909 case Intrinsic::ppc_vsx_lxvw4x:
14910 case Intrinsic::ppc_vsx_lxvw4x_be:
14913 case Intrinsic::ppc_vsx_lxvd2x:
14914 case Intrinsic::ppc_vsx_lxvd2x_be:
14917 case Intrinsic::ppc_altivec_lvebx:
14920 case Intrinsic::ppc_altivec_lvehx:
14923 case Intrinsic::ppc_altivec_lvewx:
14933 switch (
N->getConstantOperandVal(1)) {
14934 default:
return false;
14935 case Intrinsic::ppc_altivec_stvx:
14936 case Intrinsic::ppc_altivec_stvxl:
14937 case Intrinsic::ppc_vsx_stxvw4x:
14940 case Intrinsic::ppc_vsx_stxvd2x:
14943 case Intrinsic::ppc_vsx_stxvw4x_be:
14946 case Intrinsic::ppc_vsx_stxvd2x_be:
14949 case Intrinsic::ppc_altivec_stvebx:
14952 case Intrinsic::ppc_altivec_stvehx:
14955 case Intrinsic::ppc_altivec_stvewx:
14972 SDValue Chain = LD->getChain();
14973 EVT VT = LD->getMemoryVT();
14982 while (!Queue.empty()) {
14983 SDNode *ChainNext = Queue.pop_back_val();
14984 if (!Visited.
insert(ChainNext).second)
14991 if (!Visited.
count(ChainLD->getChain().getNode()))
14992 Queue.push_back(ChainLD->getChain().getNode());
14994 for (
const SDUse &O : ChainNext->
ops())
14995 if (!Visited.
count(O.getNode()))
14996 Queue.push_back(O.getNode());
14998 LoadRoots.
insert(ChainNext);
15009 for (
SDNode *
I : LoadRoots) {
15010 Queue.push_back(
I);
15012 while (!Queue.empty()) {
15013 SDNode *LoadRoot = Queue.pop_back_val();
15014 if (!Visited.
insert(LoadRoot).second)
15026 Queue.push_back(U);
15059 auto Final = Shifted;
15070 DAGCombinerInfo &DCI)
const {
15073 SelectionDAG &DAG = DCI.DAG;
15078 if (!DCI.isAfterLegalizeDAG())
15083 for (
const SDNode *U :
N->users())
15088 auto OpSize =
N->getOperand(0).getValueSizeInBits();
15092 if (OpSize <
Size) {
15110 DAGCombinerInfo &DCI)
const {
15111 SelectionDAG &DAG = DCI.DAG;
15114 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
15125 N->getValueType(0) != MVT::i1)
15128 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15129 N->getOperand(0).getValueType() != MVT::i64)
15139 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15150 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15173 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15174 N->getOperand(0).getOpcode() !=
ISD::OR &&
15175 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15185 N->getOperand(1).getOpcode() !=
ISD::AND &&
15186 N->getOperand(1).getOpcode() !=
ISD::OR &&
15187 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15198 SmallPtrSet<SDNode *, 16> Visited;
15200 for (
unsigned i = 0; i < 2; ++i) {
15204 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15216 while (!BinOps.
empty()) {
15224 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15258 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15262 for (
const SDNode *User : Inputs[i].
getNode()->
users()) {
15263 if (User !=
N && !Visited.
count(User))
15272 if (
User->getOperand(0) == Inputs[i])
15275 if (
User->getOperand(0) == Inputs[i] ||
15276 User->getOperand(1) == Inputs[i])
15282 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15283 for (
const SDNode *User : PromOps[i].
getNode()->
users()) {
15284 if (User !=
N && !Visited.
count(User))
15293 if (
User->getOperand(0) == PromOps[i])
15296 if (
User->getOperand(0) == PromOps[i] ||
15297 User->getOperand(1) == PromOps[i])
15304 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15313 std::list<HandleSDNode> PromOpHandles;
15314 for (
auto &PromOp : PromOps)
15315 PromOpHandles.emplace_back(PromOp);
15322 while (!PromOpHandles.empty()) {
15323 SDValue PromOp = PromOpHandles.back().getValue();
15324 PromOpHandles.pop_back();
15333 PromOpHandles.emplace_front(PromOp);
15347 default:
C = 0;
break;
15360 PromOpHandles.emplace_front(PromOp);
15367 for (
unsigned i = 0; i < 2; ++i)
15377 return N->getOperand(0);
15385 DAGCombinerInfo &DCI)
const {
15386 SelectionDAG &DAG = DCI.DAG;
15403 if (
N->getValueType(0) != MVT::i32 &&
15404 N->getValueType(0) != MVT::i64)
15407 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15408 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.isPPC64())))
15411 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15412 N->getOperand(0).getOpcode() !=
ISD::OR &&
15413 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15420 SmallPtrSet<SDNode *, 16> Visited;
15424 while (!BinOps.
empty()) {
15432 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15458 DenseMap<SDNode *, EVT> SelectTruncOp[2];
15463 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15468 if (User !=
N && !Visited.
count(User))
15474 if (
User->getOperand(0) == Inputs[i])
15475 SelectTruncOp[0].
insert(std::make_pair(User,
15476 User->getOperand(0).getValueType()));
15478 if (
User->getOperand(0) == Inputs[i])
15479 SelectTruncOp[0].
insert(std::make_pair(User,
15480 User->getOperand(0).getValueType()));
15481 if (
User->getOperand(1) == Inputs[i])
15482 SelectTruncOp[1].
insert(std::make_pair(User,
15483 User->getOperand(1).getValueType()));
15488 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15490 if (User !=
N && !Visited.
count(User))
15496 if (
User->getOperand(0) == PromOps[i])
15497 SelectTruncOp[0].
insert(std::make_pair(User,
15498 User->getOperand(0).getValueType()));
15500 if (
User->getOperand(0) == PromOps[i])
15501 SelectTruncOp[0].
insert(std::make_pair(User,
15502 User->getOperand(0).getValueType()));
15503 if (
User->getOperand(1) == PromOps[i])
15504 SelectTruncOp[1].
insert(std::make_pair(User,
15505 User->getOperand(1).getValueType()));
15510 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15511 bool ReallyNeedsExt =
false;
15515 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15520 Inputs[i].getOperand(0).getValueSizeInBits();
15521 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15526 OpBits-PromBits))) ||
15529 (OpBits-(PromBits-1)))) {
15530 ReallyNeedsExt =
true;
15538 std::list<HandleSDNode> PromOpHandles;
15539 for (
auto &PromOp : PromOps)
15540 PromOpHandles.emplace_back(PromOp);
15544 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15551 SDValue InSrc = Inputs[i].getOperand(0);
15569 while (!PromOpHandles.empty()) {
15571 PromOpHandles.pop_back();
15575 default:
C = 0;
break;
15588 PromOpHandles.emplace_front(PromOp);
15598 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15600 PromOpHandles.emplace_front(PromOp);
15608 for (
unsigned i = 0; i < 2; ++i) {
15626 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15627 if (SI0 != SelectTruncOp[0].
end())
15629 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15630 if (SI1 != SelectTruncOp[1].
end())
15639 if (!ReallyNeedsExt)
15640 return N->getOperand(0);
15647 N->getValueSizeInBits(0), PromBits),
15648 dl,
N->getValueType(0)));
15651 "Invalid extension type");
15654 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15662 DAGCombinerInfo &DCI)
const {
15664 "Should be called with a SETCC node");
15681 SelectionDAG &DAG = DCI.DAG;
15682 EVT VT =
N->getValueType(0);
15683 EVT OpVT =
LHS.getValueType();
15689 return DAGCombineTruncBoolExt(
N, DCI);
15696 Op.getValueType() == MVT::f64;
15708combineElementTruncationToVectorTruncation(
SDNode *
N,
15709 DAGCombinerInfo &DCI)
const {
15711 "Should be called with a BUILD_VECTOR node");
15713 SelectionDAG &DAG = DCI.DAG;
15716 SDValue FirstInput =
N->getOperand(0);
15718 "The input operand must be an fp-to-int conversion.");
15727 bool IsSplat =
true;
15732 EVT TargetVT =
N->getValueType(0);
15733 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15734 SDValue NextOp =
N->getOperand(i);
15738 if (NextConversion != FirstConversion)
15746 if (
N->getOperand(i) != FirstInput)
15757 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15758 SDValue In =
N->getOperand(i).getOperand(0);
15768 Ops.push_back(Trunc);
15771 Ops.push_back(
In.isUndef() ? DAG.
getUNDEF(SrcVT) :
In.getOperand(0));
15781 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15783 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15801 static const APInt BasePattern =
APInt(128, 0x8000000000000000ULL) << 64;
15805 if (FullVal == BasePattern)
15806 return std::make_tuple(Uim,
uint8_t{0});
15809 if (FullVal ==
APInt(128, 1))
15810 return std::make_tuple(Uim,
uint8_t{127});
15812 return std::nullopt;
15832 "Expected a BuildVectorSDNode in combineBVLoadsSpecialValue");
15836 EVT VT =
Op.getValueType();
15837 if (!(VT == MVT::v8i16 || VT == MVT::v16i8 || VT == MVT::v4i32 ||
15851 for (
const SDValue &Operand :
Op.getNode()->op_values()) {
15861 for (
unsigned Index = 0;
Index < NumElems; ++
Index) {
15865 uint64_t ElemValue =
C->getZExtValue();
15869 ElemValue &= ((1ULL << ElemBits) - 1);
15873 (IsLittleEndian) ? (Index * ElemBits) : (128 - (
Index + 1) * ElemBits);
15876 APInt ElemAPInt(128, ElemValue);
15877 ElemAPInt <<= BitPos;
15880 FullVal |= ElemAPInt;
15887 const auto &[Uim, ShiftAmount] = *UIMOpt;
15891 if (ShiftAmount == 0) {
15896 <<
"combineBVLoadsSpecialValue: Instruction Emitted ";
15897 LxvkqInstr.
dump());
15901 assert(ShiftAmount == 127 &&
"Unexpected lxvkq shift amount value");
15913 DAG.
getMachineNode(PPC::VSRQ, Dl, VT, ShiftAmountVec, ShiftAmountVec),
15916 <<
"\n combineBVLoadsSpecialValue: Instruction Emitted ";
15932 "Should be called with a BUILD_VECTOR node");
15937 if (!
N->getValueType(0).getVectorElementType().isByteSized())
15940 bool InputsAreConsecutiveLoads =
true;
15941 bool InputsAreReverseConsecutive =
true;
15942 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
15943 SDValue FirstInput =
N->getOperand(0);
15944 bool IsRoundOfExtLoad =
false;
15953 if ((!IsRoundOfExtLoad && FirstInput.
getOpcode() != ISD::LOAD) ||
15954 N->getNumOperands() == 1)
15957 if (!IsRoundOfExtLoad)
15962 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
15964 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
15967 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
15969 if (NextInput.
getOpcode() != ISD::LOAD)
15973 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
15984 InputsAreConsecutiveLoads =
false;
15986 InputsAreReverseConsecutive =
false;
15989 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15994 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15995 "The loads cannot be both consecutive and reverse consecutive.");
15999 if (InputsAreConsecutiveLoads) {
16000 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
16004 ReturnSDVal = WideLoad;
16005 }
else if (InputsAreReverseConsecutive) {
16007 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
16012 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
16020 for (
auto *LD : InputLoads)
16022 return ReturnSDVal;
16033 unsigned NumElems =
Input.getValueType().getVectorNumElements();
16039 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16041 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
16043 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
16044 CorrectElems = CorrectElems >> 8;
16045 Elems = Elems >> 8;
16052 EVT VT =
N->getValueType(0);
16056 Input.getValueType().getVectorElementType(),
16090 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
16116 Elems = Elems << 8;
16125 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
16126 if (!isSExtOfVecExtract(
N->getOperand(i))) {
16133 int TgtElemArrayIdx;
16134 int InputSize =
Input.getValueType().getScalarSizeInBits();
16135 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
16136 if (InputSize + OutputSize == 40)
16137 TgtElemArrayIdx = 0;
16138 else if (InputSize + OutputSize == 72)
16139 TgtElemArrayIdx = 1;
16140 else if (InputSize + OutputSize == 48)
16141 TgtElemArrayIdx = 2;
16142 else if (InputSize + OutputSize == 80)
16143 TgtElemArrayIdx = 3;
16144 else if (InputSize + OutputSize == 96)
16145 TgtElemArrayIdx = 4;
16149 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
16151 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
16152 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
16153 if (Elems != CorrectElems) {
16169 if (
N->getValueType(0) != MVT::v1i128)
16172 SDValue Operand =
N->getOperand(0);
16179 EVT MemoryType = LD->getMemoryVT();
16183 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
16184 MemoryType == MVT::i32 || MemoryType == MVT::i64;
16187 if (!ValidLDType ||
16193 LD->getChain(), LD->getBasePtr(),
16197 DAG.
getVTList(MVT::v1i128, MVT::Other),
16198 LoadOps, MemoryType, LD->getMemOperand());
16202 DAGCombinerInfo &DCI)
const {
16204 "Should be called with a BUILD_VECTOR node");
16206 SelectionDAG &DAG = DCI.DAG;
16209 if (!Subtarget.hasVSX())
16217 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
16232 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
16241 if (Subtarget.isISA3_1()) {
16247 if (
N->getValueType(0) != MVT::v2f64)
16258 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
16269 if (!Ext1Op || !Ext2Op)
16278 if (FirstElem == 0 && SecondElem == 1)
16279 SubvecIdx = Subtarget.isLittleEndian() ? 1 : 0;
16280 else if (FirstElem == 2 && SecondElem == 3)
16281 SubvecIdx = Subtarget.isLittleEndian() ? 0 : 1;
16288 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16293 DAGCombinerInfo &DCI)
const {
16296 "Need an int -> FP conversion node here");
16301 SelectionDAG &DAG = DCI.DAG;
16307 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16309 if (!
Op.getOperand(0).getValueType().isSimple())
16311 if (
Op.getOperand(0).getValueType().getSimpleVT() <= MVT(MVT::i1) ||
16312 Op.getOperand(0).getValueType().getSimpleVT() > MVT(MVT::i64))
16315 SDValue FirstOperand(
Op.getOperand(0));
16316 bool SubWordLoad = FirstOperand.getOpcode() == ISD::LOAD &&
16317 (FirstOperand.getValueType() == MVT::i8 ||
16318 FirstOperand.getValueType() == MVT::i16);
16319 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16321 bool DstDouble =
Op.getValueType() == MVT::f64;
16322 unsigned ConvOp =
Signed ?
16329 SDValue Ops[] = { LDN->getChain(), LDN->getBasePtr(), WidthConst };
16332 Ops, MVT::i8, LDN->getMemOperand());
16337 SDValue ExtOps[] = { Ld, WidthConst };
16339 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16341 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16349 if (
Op.getOperand(0).getValueType() == MVT::i32)
16353 "UINT_TO_FP is supported only with FPCVT");
16357 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16362 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16369 Subtarget.hasFPCVT()) ||
16371 SDValue Src =
Op.getOperand(0).getOperand(0);
16372 if (Src.getValueType() == MVT::f32) {
16373 Src = DAG.
getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
16374 DCI.AddToWorklist(Src.getNode());
16375 }
else if (Src.getValueType() != MVT::f64) {
16387 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16390 DCI.AddToWorklist(
FP.getNode());
16414 switch (
N->getOpcode()) {
16419 Chain = LD->getChain();
16420 Base = LD->getBasePtr();
16421 MMO = LD->getMemOperand();
16440 MVT VecTy =
N->getValueType(0).getSimpleVT();
16448 Chain = Load.getValue(1);
16454 if (VecTy != MVT::v2f64) {
16481 switch (
N->getOpcode()) {
16486 Chain = ST->getChain();
16487 Base = ST->getBasePtr();
16488 MMO = ST->getMemOperand();
16508 SDValue Src =
N->getOperand(SrcOpnd);
16509 MVT VecTy = Src.getValueType().getSimpleVT();
16512 if (VecTy != MVT::v2f64) {
16513 Src = DAG.
getNode(ISD::BITCAST, dl, MVT::v2f64, Src);
16518 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16524 StoreOps, VecTy, MMO);
16531 DAGCombinerInfo &DCI)
const {
16534 unsigned Opcode =
N->getOperand(1).getOpcode();
16536 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16540 &&
"Not a FP_TO_INT Instruction!");
16542 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16543 EVT Op1VT =
N->getOperand(1).getValueType();
16546 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16550 bool ValidTypeForStoreFltAsInt =
16551 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.isPPC64()) ||
16552 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16555 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16558 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16566 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16581 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16582 for (
int i = 1, e = Mask.size(); i < e; i++) {
16583 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16585 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16587 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16598 for (
int i = 0, e =
Op.getNumOperands(); i < e; i++) {
16599 FirstOp =
Op.getOperand(i);
16605 for (
int i = 1, e =
Op.getNumOperands(); i < e; i++)
16606 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16614 if (
Op.getOpcode() != ISD::BITCAST)
16616 Op =
Op.getOperand(0);
16632 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16633 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16635 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16637 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16638 for (
int I = 0,
E = ShuffV.
size();
I <
E; ++
I) {
16639 int Idx = ShuffV[
I];
16640 if (Idx >= LHSFirstElt && Idx <= LHSLastElt)
16641 ShuffV[
I] += LHSEltFixup;
16642 else if (Idx >= RHSFirstElt && Idx <= RHSLastElt)
16643 ShuffV[
I] += RHSEltFixup;
16654 SDLoc dl(OrigSToV);
16657 "Expecting a SCALAR_TO_VECTOR here");
16670 "Cannot produce a permuted scalar_to_vector for one element vector");
16672 unsigned ResultInElt = NumElts / 2;
16683 int HalfVec,
int LHSLastElementDefined,
16684 int RHSLastElementDefined) {
16685 for (
int Index : ShuffV) {
16689 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16690 (Index > LHSLastElementDefined))
16693 if ((RHSLastElementDefined >= 0) &&
16694 (Index > HalfVec + RHSLastElementDefined))
16701 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16702 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16718 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16719 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16722 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16723 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16724 return SToVPermuted;
16744 int NumElts =
LHS.getValueType().getVectorNumElements();
16747 bool IsLittleEndian = Subtarget.isLittleEndian();
16754 if (!Subtarget.hasDirectMove())
16770 SmallVector<int, 16> ShuffV(Mask);
16773 if (SToVLHS || SToVRHS) {
16776 int ShuffleNumElts = ShuffV.
size();
16777 int HalfVec = ShuffleNumElts / 2;
16783 unsigned LHSNumValidElts = HalfVec;
16784 unsigned RHSNumValidElts = HalfVec;
16789 int LHSFirstElt = 0;
16790 int RHSFirstElt = ShuffleNumElts;
16791 int LHSLastElt = -1;
16792 int RHSLastElt = -1;
16800 int LHSScalarSize = 0;
16801 int RHSScalarSize = 0;
16804 if (!IsLittleEndian && LHSScalarSize >= 64)
16809 if (!IsLittleEndian && RHSScalarSize >= 64)
16812 if (LHSScalarSize != 0)
16814 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
16815 LHSLastElt,
LHS, SToVLHS, DAG, Subtarget);
16816 if (RHSScalarSize != 0)
16818 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
16819 RHSLastElt,
RHS, SToVRHS, DAG, Subtarget);
16830 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
16831 LHSNumValidElts, RHSNumValidElts, Subtarget);
16857 if (IsLittleEndian) {
16860 if (Mask[0] < NumElts)
16861 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16865 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16870 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
16874 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
16879 if (Mask[0] < NumElts)
16880 for (
int i = 0, e =
Mask.size(); i < e; i += 2) {
16884 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
16889 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16893 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
16903 if (IsLittleEndian)
16912 DAGCombinerInfo &DCI)
const {
16914 "Not a reverse memop pattern!");
16916 auto IsElementReverse = [](
const ShuffleVectorSDNode *SVN) ->
bool {
16919 auto I =
Mask.rbegin();
16920 auto E =
Mask.rend();
16922 for (;
I !=
E; ++
I) {
16930 SelectionDAG &DAG = DCI.DAG;
16933 if (!
isTypeLegal(VT) || !Subtarget.isLittleEndian() || !Subtarget.hasVSX())
16939 if (!Subtarget.hasP9Vector())
16942 if(!IsElementReverse(SVN))
16945 if (LSBase->
getOpcode() == ISD::LOAD) {
16949 for (SDUse &Use : LSBase->
uses())
16950 if (
Use.getResNo() == 0 &&
16961 if (LSBase->
getOpcode() == ISD::STORE) {
16981 if (IntrinsicID == Intrinsic::ppc_stdcx)
16983 else if (IntrinsicID == Intrinsic::ppc_stwcx)
16985 else if (IntrinsicID == Intrinsic::ppc_sthcx)
16987 else if (IntrinsicID == Intrinsic::ppc_stbcx)
17013 switch (
N->getOpcode()) {
17016 return combineADD(
N, DCI);
17042 return combineSHL(
N, DCI);
17044 return combineSRA(
N, DCI);
17046 return combineSRL(
N, DCI);
17048 return combineMUL(
N, DCI);
17051 return combineFMALike(
N, DCI);
17054 return N->getOperand(0);
17058 return N->getOperand(0);
17064 return N->getOperand(0);
17070 return DAGCombineExtBoolTrunc(
N, DCI);
17072 return combineTRUNCATE(
N, DCI);
17074 if (
SDValue CSCC = combineSetCC(
N, DCI))
17078 return DAGCombineTruncBoolExt(
N, DCI);
17081 return combineFPToIntToFP(
N, DCI);
17090 EVT Op1VT =
N->getOperand(1).getValueType();
17091 unsigned Opcode =
N->getOperand(1).getOpcode();
17095 SDValue Val = combineStoreFPToInt(
N, DCI);
17109 N->getOperand(1).getNode()->hasOneUse() &&
17110 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
17111 (Subtarget.hasLDBRX() && Subtarget.isPPC64() && Op1VT == MVT::i64))) {
17119 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
17126 if (Op1VT.
bitsGT(mVT)) {
17131 if (Op1VT == MVT::i64)
17136 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
17156 ST->getBasePtr(), ST->getOffset(), MemVT,
17157 ST->getMemOperand(), ST->getAddressingMode(),
17161 return ST->isUnindexed()
17170 if (Subtarget.needsSwapsForVSXMemOps() &&
17171 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
17172 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
17179 EVT VT = LD->getValueType(0);
17185 if (Subtarget.needsSwapsForVSXMemOps() &&
17186 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
17187 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
17198 auto ReplaceTwoFloatLoad = [&]() {
17199 if (VT != MVT::i64)
17214 if (!LD->hasNUsesOfValue(2, 0))
17217 auto UI = LD->user_begin();
17218 while (UI.getUse().getResNo() != 0) ++UI;
17220 while (UI.getUse().getResNo() != 0) ++UI;
17221 SDNode *RightShift = *UI;
17229 if (RightShift->getOpcode() !=
ISD::SRL ||
17231 RightShift->getConstantOperandVal(1) != 32 ||
17232 !RightShift->hasOneUse())
17235 SDNode *Trunc2 = *RightShift->user_begin();
17244 if (Bitcast->getOpcode() != ISD::BITCAST ||
17245 Bitcast->getValueType(0) != MVT::f32)
17247 if (Bitcast2->
getOpcode() != ISD::BITCAST ||
17251 if (Subtarget.isLittleEndian())
17257 SDValue BasePtr = LD->getBasePtr();
17258 if (LD->isIndexed()) {
17260 "Non-pre-inc AM on PPC?");
17268 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17269 LD->getPointerInfo(), LD->getAlign(),
17270 MMOFlags, LD->getAAInfo());
17276 LD->getPointerInfo().getWithOffset(4),
17279 if (LD->isIndexed()) {
17293 if (ReplaceTwoFloatLoad())
17296 EVT MemVT = LD->getMemoryVT();
17299 if (LD->isUnindexed() && VT.
isVector() &&
17302 !Subtarget.hasP8Vector() &&
17303 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17304 VT == MVT::v4f32))) &&
17305 LD->getAlign() < ABIAlignment) {
17307 SDValue Chain = LD->getChain();
17309 bool isLittleEndian = Subtarget.isLittleEndian();
17336 MVT PermCntlTy, PermTy, LDTy;
17337 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17338 : Intrinsic::ppc_altivec_lvsl;
17339 IntrLD = Intrinsic::ppc_altivec_lvx;
17340 IntrPerm = Intrinsic::ppc_altivec_vperm;
17341 PermCntlTy = MVT::v16i8;
17342 PermTy = MVT::v4i32;
17361 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
17365 BaseLoadOps, LDTy, BaseMMO);
17374 int IncValue = IncOffset;
17391 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
17395 ExtraLoadOps, LDTy, ExtraMMO);
17406 if (isLittleEndian)
17408 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17411 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17414 Perm = Subtarget.hasAltivec()
17415 ? DAG.
getNode(ISD::BITCAST, dl, VT, Perm)
17429 bool isLittleEndian = Subtarget.isLittleEndian();
17430 unsigned IID =
N->getConstantOperandVal(0);
17431 Intrinsic::ID Intr = (isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17432 : Intrinsic::ppc_altivec_lvsl);
17433 if (IID == Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17440 .zext(
Add.getScalarValueSizeInBits()))) {
17441 SDNode *BasePtr =
Add->getOperand(0).getNode();
17442 for (
SDNode *U : BasePtr->users()) {
17444 U->getConstantOperandVal(0) == IID) {
17455 SDNode *BasePtr =
Add->getOperand(0).getNode();
17456 for (
SDNode *U : BasePtr->users()) {
17459 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17465 V->getConstantOperandVal(0) == IID) {
17477 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17478 IID == Intrinsic::ppc_altivec_vmaxsh ||
17479 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17510 switch (
N->getConstantOperandVal(1)) {
17513 case Intrinsic::ppc_altivec_vsum4sbs:
17514 case Intrinsic::ppc_altivec_vsum4shs:
17515 case Intrinsic::ppc_altivec_vsum4ubs: {
17522 APInt APSplatBits, APSplatUndef;
17523 unsigned SplatBitSize;
17526 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17527 !Subtarget.isLittleEndian());
17529 if (BVNIsConstantSplat && APSplatBits == 0)
17534 case Intrinsic::ppc_vsx_lxvw4x:
17535 case Intrinsic::ppc_vsx_lxvd2x:
17538 if (Subtarget.needsSwapsForVSXMemOps())
17546 if (Subtarget.needsSwapsForVSXMemOps()) {
17547 switch (
N->getConstantOperandVal(1)) {
17550 case Intrinsic::ppc_vsx_stxvw4x:
17551 case Intrinsic::ppc_vsx_stxvd2x:
17560 bool Is64BitBswapOn64BitTgt =
17561 Subtarget.isPPC64() &&
N->getValueType(0) == MVT::i64;
17563 N->getOperand(0).hasOneUse();
17564 if (IsSingleUseNormalLd &&
17565 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17566 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17577 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17578 MVT::i64 : MVT::i32, MVT::Other),
17579 Ops, LD->getMemoryVT(), LD->getMemOperand());
17583 if (
N->getValueType(0) == MVT::i16)
17600 !IsSingleUseNormalLd)
17605 if (!LD->isSimple())
17607 SDValue BasePtr = LD->getBasePtr();
17609 LD->getPointerInfo(), LD->getAlign());
17614 LD->getMemOperand(), 4, 4);
17618 if (Subtarget.isLittleEndian())
17624 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
17633 if (!
N->getOperand(0).hasOneUse() &&
17634 !
N->getOperand(1).hasOneUse() &&
17635 !
N->getOperand(2).hasOneUse()) {
17638 SDNode *VCMPrecNode =
nullptr;
17640 SDNode *LHSN =
N->getOperand(0).getNode();
17646 VCMPrecNode =
User;
17658 SDNode *FlagUser =
nullptr;
17660 FlagUser ==
nullptr; ++UI) {
17661 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
17674 return SDValue(VCMPrecNode, 0);
17685 SDValue LHS =
N->getOperand(2), RHS =
N->getOperand(3);
17696 auto RHSAPInt = RHS->getAsAPIntVal();
17697 if (!RHSAPInt.isIntN(64))
17700 unsigned Val = RHSAPInt.getZExtValue();
17701 auto isImpossibleCompare = [&]() {
17704 if (Val != 0 && Val != 1) {
17706 return N->getOperand(0);
17708 return DAG.
getNode(ISD::BR, dl, MVT::Other,
17709 N->getOperand(0),
N->getOperand(4));
17714 unsigned StoreWidth = 0;
17717 if (
SDValue Impossible = isImpossibleCompare())
17729 SDValue Ops[] = {LHS.getOperand(0), LHS.getOperand(2), LHS.getOperand(3),
17735 MemNode->getMemoryVT(), MemNode->getMemOperand());
17739 if (
N->getOperand(0) == LHS.getValue(1))
17752 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
17758 assert(isDot &&
"Can't compare against a vector result!");
17760 if (
SDValue Impossible = isImpossibleCompare())
17763 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
17770 EVT VTs[] = { LHS.getOperand(2).getValueType(), MVT::Glue };
17775 switch (LHS.getConstantOperandVal(1)) {
17794 N->getOperand(4), CompNode.
getValue(1));
17799 return DAGCombineBuildVector(
N, DCI);
17812 EVT VT =
N->getValueType(0);
17813 if (VT == MVT::i64 && !Subtarget.isPPC64())
17815 if ((VT != MVT::i32 && VT != MVT::i64) ||
17823 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
17843 const APInt &DemandedElts,
17845 unsigned Depth)
const {
17847 switch (
Op.getOpcode()) {
17852 Known.
Zero = 0xFFFF0000;
17856 if (
Op.getResNo() == 0) {
17861 Known.
Zero = ~1ULL;
17866 switch (
Op.getConstantOperandVal(0)) {
17868 case Intrinsic::ppc_altivec_vcmpbfp_p:
17869 case Intrinsic::ppc_altivec_vcmpeqfp_p:
17870 case Intrinsic::ppc_altivec_vcmpequb_p:
17871 case Intrinsic::ppc_altivec_vcmpequh_p:
17872 case Intrinsic::ppc_altivec_vcmpequw_p:
17873 case Intrinsic::ppc_altivec_vcmpequd_p:
17874 case Intrinsic::ppc_altivec_vcmpequq_p:
17875 case Intrinsic::ppc_altivec_vcmpgefp_p:
17876 case Intrinsic::ppc_altivec_vcmpgtfp_p:
17877 case Intrinsic::ppc_altivec_vcmpgtsb_p:
17878 case Intrinsic::ppc_altivec_vcmpgtsh_p:
17879 case Intrinsic::ppc_altivec_vcmpgtsw_p:
17880 case Intrinsic::ppc_altivec_vcmpgtsd_p:
17881 case Intrinsic::ppc_altivec_vcmpgtsq_p:
17882 case Intrinsic::ppc_altivec_vcmpgtub_p:
17883 case Intrinsic::ppc_altivec_vcmpgtuh_p:
17884 case Intrinsic::ppc_altivec_vcmpgtuw_p:
17885 case Intrinsic::ppc_altivec_vcmpgtud_p:
17886 case Intrinsic::ppc_altivec_vcmpgtuq_p:
17893 switch (
Op.getConstantOperandVal(1)) {
17896 case Intrinsic::ppc_load2r:
17898 Known.
Zero = 0xFFFF0000;
17907 switch (Subtarget.getCPUDirective()) {
17929 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
17938 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
17940 LoopSize +=
TII->getInstSizeInBytes(J);
17945 if (LoopSize > 16 && LoopSize <= 32)
17959 if (Constraint.
size() == 1) {
17960 switch (Constraint[0]) {
17978 }
else if (Constraint ==
"wc") {
17980 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
17981 Constraint ==
"wf" || Constraint ==
"ws" ||
17982 Constraint ==
"wi" || Constraint ==
"ww") {
17995 Value *CallOperandVal =
info.CallOperandVal;
17998 if (!CallOperandVal)
18005 else if ((
StringRef(constraint) ==
"wa" ||
18017 switch (*constraint) {
18047std::pair<unsigned, const TargetRegisterClass *>
18051 if (Constraint.
size() == 1) {
18053 switch (Constraint[0]) {
18055 if (VT == MVT::i64 && Subtarget.isPPC64())
18056 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
18057 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
18059 if (VT == MVT::i64 && Subtarget.isPPC64())
18060 return std::make_pair(0U, &PPC::G8RCRegClass);
18061 return std::make_pair(0U, &PPC::GPRCRegClass);
18067 if (Subtarget.hasSPE()) {
18068 if (VT == MVT::f32 || VT == MVT::i32)
18069 return std::make_pair(0U, &PPC::GPRCRegClass);
18070 if (VT == MVT::f64 || VT == MVT::i64)
18071 return std::make_pair(0U, &PPC::SPERCRegClass);
18073 if (VT == MVT::f32 || VT == MVT::i32)
18074 return std::make_pair(0U, &PPC::F4RCRegClass);
18075 if (VT == MVT::f64 || VT == MVT::i64)
18076 return std::make_pair(0U, &PPC::F8RCRegClass);
18080 if (Subtarget.hasAltivec() && VT.
isVector())
18081 return std::make_pair(0U, &PPC::VRRCRegClass);
18082 else if (Subtarget.hasVSX())
18084 return std::make_pair(0U, &PPC::VFRCRegClass);
18087 return std::make_pair(0U, &PPC::CRRCRegClass);
18089 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
18091 return std::make_pair(0U, &PPC::CRBITRCRegClass);
18092 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
18093 Constraint ==
"wf" || Constraint ==
"wi") &&
18094 Subtarget.hasVSX()) {
18098 return std::make_pair(0U, &PPC::VSRCRegClass);
18099 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18100 return std::make_pair(0U, &PPC::VSSRCRegClass);
18101 return std::make_pair(0U, &PPC::VSFRCRegClass);
18102 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
18103 if (VT == MVT::f32 && Subtarget.hasP8Vector())
18104 return std::make_pair(0U, &PPC::VSSRCRegClass);
18106 return std::make_pair(0U, &PPC::VSFRCRegClass);
18107 }
else if (Constraint ==
"lr") {
18108 if (VT == MVT::i64)
18109 return std::make_pair(0U, &PPC::LR8RCRegClass);
18111 return std::make_pair(0U, &PPC::LRRCRegClass);
18116 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
18120 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
18121 int VSNum = atoi(Constraint.
data() + 3);
18122 assert(VSNum >= 0 && VSNum <= 63 &&
18123 "Attempted to access a vsr out of range");
18125 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
18126 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
18131 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
18132 int RegNum = atoi(Constraint.
data() + 2);
18133 if (RegNum > 31 || RegNum < 0)
18135 if (VT == MVT::f32 || VT == MVT::i32)
18136 return Subtarget.hasSPE()
18137 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
18138 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
18139 if (VT == MVT::f64 || VT == MVT::i64)
18140 return Subtarget.hasSPE()
18141 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
18142 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
18146 std::pair<unsigned, const TargetRegisterClass *> R =
18155 if (R.first && VT == MVT::i64 && Subtarget.isPPC64() &&
18156 PPC::GPRCRegClass.contains(R.first))
18157 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
18158 PPC::sub_32, &PPC::G8RCRegClass),
18159 &PPC::G8RCRegClass);
18162 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
18163 R.first = PPC::CR0;
18164 R.second = &PPC::CRRCRegClass;
18168 if (Subtarget.isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
18169 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
18170 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
18171 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
18172 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
18173 "default AIX AltiVec ABI and cannot be used\n";
18183 std::vector<SDValue> &
Ops,
18188 if (Constraint.
size() > 1)
18191 char Letter = Constraint[0];
18206 EVT TCVT = MVT::i64;
18247 if (Result.getNode()) {
18248 Ops.push_back(Result);
18259 if (
I.getNumOperands() <= 1)
18263 auto IntrinsicID =
Ops[1].getNode()->getAsZExtVal();
18264 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
18265 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18268 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18284 if (Ty->isVectorTy() && AM.
BaseOffs != 0 && !Subtarget.hasP9Vector())
18296 switch (AM.
Scale) {
18324 unsigned Depth =
Op.getConstantOperandVal(0);
18348 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18356 unsigned Depth =
Op.getConstantOperandVal(0);
18363 bool isPPC64 = PtrVT == MVT::i64;
18369 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18371 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18377 FrameAddr, MachinePointerInfo());
18381#define GET_REGISTER_MATCHER
18382#include "PPCGenAsmMatcher.inc"
18386 bool IsPPC64 = Subtarget.isPPC64();
18398 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18404 Reg = Reg.id() - PPC::R0 + PPC::X0;
18411 if (Subtarget.is32BitELFABI())
18416 if (Subtarget.isAIXABI())
18430 return Subtarget.isGVIndirectSymbol(
G->getGlobal());
18446 case Intrinsic::ppc_atomicrmw_xchg_i128:
18447 case Intrinsic::ppc_atomicrmw_add_i128:
18448 case Intrinsic::ppc_atomicrmw_sub_i128:
18449 case Intrinsic::ppc_atomicrmw_nand_i128:
18450 case Intrinsic::ppc_atomicrmw_and_i128:
18451 case Intrinsic::ppc_atomicrmw_or_i128:
18452 case Intrinsic::ppc_atomicrmw_xor_i128:
18453 case Intrinsic::ppc_cmpxchg_i128:
18455 Info.memVT = MVT::i128;
18456 Info.ptrVal =
I.getArgOperand(0);
18458 Info.align =
Align(16);
18462 case Intrinsic::ppc_atomic_load_i128:
18464 Info.memVT = MVT::i128;
18465 Info.ptrVal =
I.getArgOperand(0);
18467 Info.align =
Align(16);
18470 case Intrinsic::ppc_atomic_store_i128:
18472 Info.memVT = MVT::i128;
18473 Info.ptrVal =
I.getArgOperand(2);
18475 Info.align =
Align(16);
18478 case Intrinsic::ppc_altivec_lvx:
18479 case Intrinsic::ppc_altivec_lvxl:
18480 case Intrinsic::ppc_altivec_lvebx:
18481 case Intrinsic::ppc_altivec_lvehx:
18482 case Intrinsic::ppc_altivec_lvewx:
18483 case Intrinsic::ppc_vsx_lxvd2x:
18484 case Intrinsic::ppc_vsx_lxvw4x:
18485 case Intrinsic::ppc_vsx_lxvd2x_be:
18486 case Intrinsic::ppc_vsx_lxvw4x_be:
18487 case Intrinsic::ppc_vsx_lxvl:
18488 case Intrinsic::ppc_vsx_lxvll: {
18491 case Intrinsic::ppc_altivec_lvebx:
18494 case Intrinsic::ppc_altivec_lvehx:
18497 case Intrinsic::ppc_altivec_lvewx:
18500 case Intrinsic::ppc_vsx_lxvd2x:
18501 case Intrinsic::ppc_vsx_lxvd2x_be:
18511 Info.ptrVal =
I.getArgOperand(0);
18514 Info.align =
Align(1);
18518 case Intrinsic::ppc_altivec_stvx:
18519 case Intrinsic::ppc_altivec_stvxl:
18520 case Intrinsic::ppc_altivec_stvebx:
18521 case Intrinsic::ppc_altivec_stvehx:
18522 case Intrinsic::ppc_altivec_stvewx:
18523 case Intrinsic::ppc_vsx_stxvd2x:
18524 case Intrinsic::ppc_vsx_stxvw4x:
18525 case Intrinsic::ppc_vsx_stxvd2x_be:
18526 case Intrinsic::ppc_vsx_stxvw4x_be:
18527 case Intrinsic::ppc_vsx_stxvl:
18528 case Intrinsic::ppc_vsx_stxvll: {
18531 case Intrinsic::ppc_altivec_stvebx:
18534 case Intrinsic::ppc_altivec_stvehx:
18537 case Intrinsic::ppc_altivec_stvewx:
18540 case Intrinsic::ppc_vsx_stxvd2x:
18541 case Intrinsic::ppc_vsx_stxvd2x_be:
18551 Info.ptrVal =
I.getArgOperand(1);
18554 Info.align =
Align(1);
18558 case Intrinsic::ppc_stdcx:
18559 case Intrinsic::ppc_stwcx:
18560 case Intrinsic::ppc_sthcx:
18561 case Intrinsic::ppc_stbcx: {
18563 auto Alignment =
Align(8);
18565 case Intrinsic::ppc_stdcx:
18568 case Intrinsic::ppc_stwcx:
18570 Alignment =
Align(4);
18572 case Intrinsic::ppc_sthcx:
18574 Alignment =
Align(2);
18576 case Intrinsic::ppc_stbcx:
18578 Alignment =
Align(1);
18583 Info.ptrVal =
I.getArgOperand(0);
18585 Info.align = Alignment;
18600 const AttributeList &FuncAttributes)
const {
18604 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
18605 if (
Op.isMemset() && Subtarget.hasVSX()) {
18610 if (TailSize > 2 && TailSize <= 4) {
18615 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
18620 if (Subtarget.isPPC64()) {
18631 assert(Ty->isIntegerTy());
18633 unsigned BitSize = Ty->getPrimitiveSizeInBits();
18634 return !(BitSize == 0 || BitSize > 64);
18642 return NumBits1 == 64 && NumBits2 == 32;
18650 return NumBits1 == 64 && NumBits2 == 32;
18657 EVT MemVT = LD->getMemoryVT();
18658 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
18659 (Subtarget.isPPC64() && MemVT == MVT::i32)) &&
18675 "invalid fpext types");
18677 if (DestVT == MVT::f128)
18692 unsigned *
Fast)
const {
18706 !Subtarget.allowsUnalignedFPAccess())
18710 if (Subtarget.hasVSX()) {
18711 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
18712 VT != MVT::v4f32 && VT != MVT::v4i32)
18719 if (VT == MVT::ppcf128)
18734 if (!ConstNode->getAPIntValue().isSignedIntN(64))
18742 int64_t Imm = ConstNode->getSExtValue();
18763 if (Subtarget.hasSPE() || Subtarget.useSoftFloat())
18765 switch (Ty->getScalarType()->getTypeID()) {
18770 return Subtarget.hasP9Vector();
18778 if (!
I->hasOneUse())
18782 assert(
User &&
"A single use instruction with no uses.");
18784 switch (
I->getOpcode()) {
18785 case Instruction::FMul: {
18787 if (
User->getOpcode() != Instruction::FSub &&
18788 User->getOpcode() != Instruction::FAdd)
18795 bool AllowContract =
I->getFastMathFlags().allowContract() &&
18796 User->getFastMathFlags().allowContract();
18802 case Instruction::Load: {
18815 if (
User->getOpcode() != Instruction::Store)
18835 static const MCPhysReg ScratchRegs[] = {
18836 PPC::X12, PPC::LR8, PPC::CTR8, 0
18839 return ScratchRegs;
18843 const Constant *PersonalityFn)
const {
18844 return Subtarget.isPPC64() ? PPC::X3 : PPC::R3;
18848 const Constant *PersonalityFn)
const {
18849 return Subtarget.isPPC64() ? PPC::X4 : PPC::R4;
18854 EVT VT ,
unsigned DefinedValues)
const {
18855 if (VT == MVT::v2i64)
18856 return Subtarget.hasDirectMove();
18858 if (Subtarget.hasVSX())
18892 bool LegalOps,
bool OptForSize,
18894 unsigned Depth)
const {
18898 unsigned Opc =
Op.getOpcode();
18899 EVT VT =
Op.getValueType();
18924 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
18928 N0Cost,
Depth + 1);
18932 N1Cost,
Depth + 1);
18934 if (NegN0 && N0Cost <= N1Cost) {
18935 Cost = std::min(N0Cost, N2Cost);
18937 }
else if (NegN1) {
18938 Cost = std::min(N1Cost, N2Cost);
18958 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.isTargetLinux())
18964 bool ForCodeSize)
const {
18965 if (!VT.
isSimple() || !Subtarget.hasVSX())
18975 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
18980 APSInt IntResult(16,
false);
18985 if (IsExact && IntResult <= 15 && IntResult >= -16)
18987 return Imm.isZero();
18990 return Imm.isPosZero();
19002 unsigned Opcode =
N->getOpcode();
19022 if (Mask->getZExtValue() == OpSizeInBits - 1)
19029 DAGCombinerInfo &DCI)
const {
19030 EVT VT =
N->getValueType(0);
19033 unsigned Opc =
N->getOpcode();
19035 "Unexpected opcode.");
19042 if (EltTy != MVT::i64 && EltTy != MVT::i32)
19046 uint64_t SplatBits = 0;
19047 bool AddSplatCase =
false;
19051 AddSplatCase =
true;
19055 if (!AddSplatCase) {
19059 unsigned SplatBitSize;
19061 APInt APSplatBits, APSplatUndef;
19063 bool BVNIsConstantSplat =
19065 HasAnyUndefs, 0, !Subtarget.isLittleEndian());
19066 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
19077 if (SplatBits == (EltBits - 1)) {
19091 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
19099 if (EltTy != MVT::i64 || SplatBits != 1)
19102 return DCI.DAG.getNode(
ISD::ADD, SDLoc(
N), VT, N0, N0);
19105SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19109 if (
N->getValueType(0).isVector())
19110 return combineVectorShift(
N, DCI);
19114 if (!Subtarget.isISA3_0() || !Subtarget.isPPC64() ||
19117 N->getValueType(0) != MVT::i64)
19132 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
19138SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19142 if (
N->getValueType(0).isVector())
19143 return combineVectorShift(
N, DCI);
19148SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19152 if (
N->getValueType(0).isVector())
19153 return combineVectorShift(
N, DCI);
19164 if (!Subtarget.isPPC64())
19170 auto isZextOfCompareWithConstant = [](
SDValue Op) {
19172 Op.getValueType() != MVT::i64)
19176 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
19177 Cmp.getOperand(0).getValueType() != MVT::i64)
19181 int64_t NegConstant = 0 -
Constant->getSExtValue();
19190 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
19191 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
19194 if (LHSHasPattern && !RHSHasPattern)
19196 else if (!LHSHasPattern && !RHSHasPattern)
19200 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
19203 SDValue Z = Cmp.getOperand(0);
19205 int64_t NegConstant = 0 -
Constant->getSExtValue();
19218 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19236 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19277 if (!GSDN || !ConstNode)
19297SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19317 DAGCombinerInfo &DCI)
const {
19319 if (Subtarget.useCRBits()) {
19321 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19322 return CRTruncValue;
19329 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19332 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19342 EltToExtract = EltToExtract ? 0 : 1;
19352 return DCI.DAG.getNode(
19354 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19359SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19360 SelectionDAG &DAG = DCI.DAG;
19363 if (!ConstOpOrElement)
19371 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne, EVT VT) ->
bool {
19372 switch (this->Subtarget.getCPUDirective()) {
19395 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19399 EVT VT =
N->getValueType(0);
19404 APInt MulAmtAbs = MulAmt.
abs();
19406 if ((MulAmtAbs - 1).isPowerOf2()) {
19410 if (!IsProfitable(IsNeg,
true, VT))
19423 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19427 if (!IsProfitable(IsNeg,
false, VT))
19448 DAGCombinerInfo &DCI)
const {
19452 SDNodeFlags
Flags =
N->getFlags();
19453 EVT VT =
N->getValueType(0);
19454 SelectionDAG &DAG = DCI.DAG;
19456 unsigned Opc =
N->getOpcode();
19458 bool LegalOps = !DCI.isBeforeLegalizeOps();
19466 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
19482bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19484 if (!Subtarget.is64BitELFABI())
19494 if (!TM.Options.GuaranteedTailCallOpt &&
DisableSCO)
19499 if (!Callee ||
Callee->isVarArg())
19512bool PPCTargetLowering::
19513isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19518 if (CI->getBitWidth() > 64)
19520 int64_t ConstVal = CI->getZExtValue();
19522 (
isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19531PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19537 if ((Flags & FlagSet) == FlagSet)
19540 if ((Flags & FlagSet) == FlagSet)
19543 if ((Flags & FlagSet) == FlagSet)
19546 if ((Flags & FlagSet) == FlagSet)
19567 if ((FrameIndexAlign % 4) != 0)
19568 FlagSet &=
~PPC::MOF_RPlusSImm16Mult4;
19569 if ((FrameIndexAlign % 16) != 0)
19570 FlagSet &=
~PPC::MOF_RPlusSImm16Mult16;
19574 if ((FrameIndexAlign % 4) == 0)
19576 if ((FrameIndexAlign % 16) == 0)
19589 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
19590 if ((Imm & 0x3) == 0)
19592 if ((Imm & 0xf) == 0)
19598 const APInt &ConstImm = CN->getAPIntValue();
19617 const APInt &ConstImm = CN->getAPIntValue();
19627 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
19647unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
19652 if (!Subtarget.hasP9Vector())
19657 if (Subtarget.hasPrefixInstrs())
19660 if (Subtarget.hasSPE())
19669 unsigned ParentOp = Parent->
getOpcode();
19673 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
19674 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
19686 if (LSB->isIndexed())
19692 assert(MN &&
"Parent should be a MemSDNode!");
19697 "Not expecting scalar integers larger than 16 bytes!");
19700 else if (
Size == 32)
19707 else if (
Size == 256) {
19708 assert(Subtarget.pairedVectorMemops() &&
19709 "256-bit vectors are only available when paired vector memops is "
19717 else if (MemVT == MVT::f128 || MemVT.
isVector())
19748 FlagSet &= ~PPC::MOF_NoExt;
19753 bool IsNonP1034BitConst =
19757 IsNonP1034BitConst)
19770 int16_t ForceXFormImm = 0;
19773 Disp =
N.getOperand(0);
19774 Base =
N.getOperand(1);
19785 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
19786 Disp =
N.getOperand(0);
19787 Base =
N.getOperand(1);
19792 Disp = DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
19801 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
19807 if (PartVT == MVT::f64 &&
19808 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
19810 Val = DAG.
getNode(ISD::BITCAST,
DL, MVT::f64, Val);
19817SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
19821 EVT RetVT =
Op.getValueType();
19828 EVT ArgVT =
N.getValueType();
19832 Entry.IsZExt = !Entry.IsSExt;
19833 Args.push_back(Entry);
19841 (RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
19854SDValue PPCTargetLowering::lowerLibCallBasedOnType(
19855 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
19857 if (
Op.getValueType() == MVT::f32)
19858 return lowerToLibCall(LibCallFloatName,
Op, DAG);
19860 if (
Op.getValueType() == MVT::f64)
19861 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
19866bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
19867 SDNodeFlags
Flags =
Op.getNode()->getFlags();
19868 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
19872bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
19873 return Op.getNode()->getFlags().hasApproximateFuncs();
19876bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
19880SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
19881 const char *LibCallFloatName,
19882 const char *LibCallDoubleNameFinite,
19883 const char *LibCallFloatNameFinite,
19886 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
19889 if (!isLowringToMASSFiniteSafe(
Op))
19890 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
19893 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
19894 LibCallDoubleNameFinite,
Op, DAG);
19898 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
19899 "__xl_powf_finite",
Op, DAG);
19903 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
19904 "__xl_sinf_finite",
Op, DAG);
19908 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
19909 "__xl_cosf_finite",
Op, DAG);
19913 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
19914 "__xl_logf_finite",
Op, DAG);
19918 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
19919 "__xl_log10f_finite",
Op, DAG);
19923 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
19924 "__xl_expf_finite",
Op, DAG);
19949 unsigned Flags = computeMOFlags(Parent,
N, DAG);
19960 assert(Subtarget.isUsingPCRelativeCalls() &&
19961 "Must be using PC-Relative calls when a valid PC-Relative node is "
19991 Disp =
N.getOperand(1).getOperand(0);
19996 Base =
N.getOperand(0);
20004 EVT CNType = CN->getValueType(0);
20005 uint64_t CNImm = CN->getZExtValue();
20016 if ((CNType == MVT::i32 ||
isInt<32>(CNImm)) &&
20018 int32_t Addr = (int32_t)CNImm;
20023 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
20039 unsigned Opcode =
N.getOpcode();
20047 Base =
N.getOperand(0);
20066 Base = FI ?
N :
N.getOperand(1);
20067 Disp = FI ? DAG.
getRegister(Subtarget.isPPC64() ? PPC::ZERO8 : PPC::ZERO,
20078 bool IsVarArg)
const {
20088 return Subtarget.isPPC64() && Subtarget.hasQuadwordAtomics();
20124 return Intrinsic::ppc_atomicrmw_xchg_i128;
20126 return Intrinsic::ppc_atomicrmw_add_i128;
20128 return Intrinsic::ppc_atomicrmw_sub_i128;
20130 return Intrinsic::ppc_atomicrmw_and_i128;
20132 return Intrinsic::ppc_atomicrmw_or_i128;
20134 return Intrinsic::ppc_atomicrmw_xor_i128;
20136 return Intrinsic::ppc_atomicrmw_nand_i128;
20144 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20146 assert(ValTy->getPrimitiveSizeInBits() == 128);
20148 Value *IncrLo = Builder.CreateTrunc(Incr, Int64Ty,
"incr_lo");
20150 Builder.CreateTrunc(Builder.CreateLShr(Incr, 64), Int64Ty,
"incr_hi");
20151 Value *LoHi = Builder.CreateIntrinsic(
20153 {AlignedAddr, IncrLo, IncrHi});
20154 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20155 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20156 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20157 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20158 return Builder.CreateOr(
20159 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20166 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
20168 assert(ValTy->getPrimitiveSizeInBits() == 128);
20172 Value *CmpLo = Builder.CreateTrunc(CmpVal, Int64Ty,
"cmp_lo");
20174 Builder.CreateTrunc(Builder.CreateLShr(CmpVal, 64), Int64Ty,
"cmp_hi");
20175 Value *NewLo = Builder.CreateTrunc(NewVal, Int64Ty,
"new_lo");
20177 Builder.CreateTrunc(Builder.CreateLShr(NewVal, 64), Int64Ty,
"new_hi");
20180 Builder.CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
20182 Value *
Lo = Builder.CreateExtractValue(LoHi, 0,
"lo");
20183 Value *
Hi = Builder.CreateExtractValue(LoHi, 1,
"hi");
20184 Lo = Builder.CreateZExt(
Lo, ValTy,
"lo64");
20185 Hi = Builder.CreateZExt(
Hi, ValTy,
"hi64");
20186 return Builder.CreateOr(
20187 Lo, Builder.CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
20191 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< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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)
std::tuple< uint32_t, uint8_t > LXVKQPattern
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static 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 cl::opt< unsigned > PPCMinimumBitTestCmps("ppc-min-bit-test-cmps", cl::init(3), cl::Hidden, cl::desc("Set minimum of largest number of comparisons to use bit test for " "switch on PPC."))
static 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 SDValue AdjustLength(SDValue Val, unsigned Bits, bool Left, SelectionDAG &DAG)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static std::optional< LXVKQPattern > getPatternInfo(const APInt &FullVal)
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.
static const fltSemantics & IEEEsingle()
static constexpr roundingMode rmTowardZero
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble()
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
bool isZero() const
Determine if this value is zero, i.e. all bits are clear.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
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.
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
const Argument * const_arg_iterator
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
LLVM_ABI StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
LLVM_ABI bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
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 getFreeze(SDValue V)
Return a freeze using the SDLoc of the value operand.
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
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
void setMinimumBitTestCmps(unsigned Val)
Set the minimum of largest of number of comparisons to generate BitTest.
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
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 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.
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ 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.
@ Increment
Incrementally increasing token ID.
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,...
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool 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.
LLVM_ABI std::string getEVTString() const
This function returns value type as a string, e.g. "i32".
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.