68#include "llvm/IR/IntrinsicsPowerPC.h"
102#define DEBUG_TYPE "ppc-lowering"
105 "disable-p10-store-forward",
129 cl::desc(
"disable vector permute decomposition"),
133 "disable-auto-paired-vec-st",
134 cl::desc(
"disable automatically generated 32byte paired vector stores"),
139 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
143 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
147 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
148 "function to use initial-exec"));
153 "Number of shuffles lowered to a VPERM or XXPERM");
154STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
175 initializeAddrModeMap();
178 bool isPPC64 = Subtarget.
isPPC64();
188 if (!Subtarget.hasEFPU2())
205 if (!Subtarget.hasP10Vector()) {
231 if (Subtarget.isISA3_0()) {
264 if (!Subtarget.hasSPE()) {
271 if (Subtarget.useCRBits()) {
274 if (isPPC64 || Subtarget.hasFPCVT()) {
340 if (Subtarget.isISA3_0()) {
375 if (!Subtarget.hasSPE()) {
380 if (Subtarget.hasVSX()) {
385 if (Subtarget.hasFSQRT()) {
390 if (Subtarget.hasFPRND()) {
431 if (Subtarget.hasSPE()) {
441 if (Subtarget.hasSPE())
445 if (!Subtarget.hasFSQRT() &&
446 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
450 if (!Subtarget.hasFSQRT() &&
451 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
452 Subtarget.hasFRES()))
455 if (Subtarget.hasFCPSGN()) {
463 if (Subtarget.hasFPRND()) {
477 if (Subtarget.isISA3_1()) {
483 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
487 if (Subtarget.isISA3_0()) {
507 if (!Subtarget.useCRBits()) {
520 if (!Subtarget.useCRBits())
523 if (Subtarget.hasFPU()) {
534 if (!Subtarget.useCRBits())
539 if (Subtarget.hasSPE()) {
563 if (Subtarget.hasDirectMove() && isPPC64) {
568 if (TM.Options.UnsafeFPMath) {
671 if (Subtarget.hasSPE()) {
693 if (Subtarget.has64BitSupport()) {
708 if (Subtarget.hasLFIWAX() || isPPC64) {
714 if (Subtarget.hasSPE()) {
724 if (Subtarget.hasFPCVT()) {
725 if (Subtarget.has64BitSupport()) {
746 if (Subtarget.use64BitRegs()) {
764 if (Subtarget.has64BitSupport()) {
771 if (Subtarget.hasVSX()) {
780 if (Subtarget.hasAltivec()) {
781 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
796 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
809 if (Subtarget.hasVSX()) {
815 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
825 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
899 if (!Subtarget.hasP8Vector()) {
941 if (Subtarget.hasAltivec())
942 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
945 if (Subtarget.hasP8Altivec())
956 if (Subtarget.hasVSX()) {
962 if (Subtarget.hasP8Altivec())
967 if (Subtarget.isISA3_1()) {
1013 if (Subtarget.hasVSX()) {
1016 if (Subtarget.hasP8Vector()) {
1020 if (Subtarget.hasDirectMove() && isPPC64) {
1034 if (TM.Options.UnsafeFPMath) {
1071 if (Subtarget.hasP8Vector())
1080 if (Subtarget.hasP8Altivec()) {
1107 if (Subtarget.isISA3_1())
1210 if (Subtarget.hasP8Altivec()) {
1215 if (Subtarget.hasP9Vector()) {
1220 if (Subtarget.useCRBits()) {
1280 }
else if (Subtarget.hasVSX()) {
1305 for (
MVT VT : {MVT::f32, MVT::f64}) {
1324 if (Subtarget.hasP9Altivec()) {
1325 if (Subtarget.isISA3_1()) {
1348 if (Subtarget.hasP10Vector()) {
1353 if (Subtarget.pairedVectorMemops()) {
1358 if (Subtarget.hasMMA()) {
1359 if (Subtarget.isISAFuture()) {
1375 if (Subtarget.has64BitSupport())
1378 if (Subtarget.isISA3_1())
1396 if (Subtarget.hasAltivec()) {
1413 if (Subtarget.hasFPCVT())
1416 if (Subtarget.useCRBits())
1425 if (Subtarget.useCRBits()) {
1431 if (Subtarget.useCRBits()) {
1445 switch (CPUDirective) {
1542void PPCTargetLowering::initializeAddrModeMap() {
1593 if (MaxAlign == MaxMaxAlign)
1595 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1596 if (MaxMaxAlign >= 32 &&
1597 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1598 MaxAlign =
Align(32);
1599 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1601 MaxAlign =
Align(16);
1602 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1605 if (EltAlign > MaxAlign)
1606 MaxAlign = EltAlign;
1607 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1608 for (
auto *EltTy : STy->elements()) {
1611 if (EltAlign > MaxAlign)
1612 MaxAlign = EltAlign;
1613 if (MaxAlign == MaxMaxAlign)
1626 if (Subtarget.hasAltivec())
1636 return Subtarget.hasSPE();
1644 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1645 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1648 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1649 if (VTy->getScalarType()->isIntegerTy()) {
1651 if (ElemSizeInBits == 32) {
1655 if (ElemSizeInBits == 64) {
1681 return "PPCISD::FTSQRT";
1683 return "PPCISD::FSQRT";
1688 return "PPCISD::XXSPLTI_SP_TO_DP";
1690 return "PPCISD::XXSPLTI32DX";
1694 return "PPCISD::XXPERM";
1714 return "PPCISD::CALL_RM";
1716 return "PPCISD::CALL_NOP_RM";
1718 return "PPCISD::CALL_NOTOC_RM";
1723 return "PPCISD::BCTRL_RM";
1725 return "PPCISD::BCTRL_LOAD_TOC_RM";
1737 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1739 return "PPCISD::ANDI_rec_1_EQ_BIT";
1741 return "PPCISD::ANDI_rec_1_GT_BIT";
1756 return "PPCISD::ST_VSR_SCAL_INT";
1785 return "PPCISD::PADDI_DTPREL";
1787 return "PPCISD::VADD_SPLAT";
1798 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1800 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1810 return "PPCISD::STRICT_FADDRTZ";
1812 return "PPCISD::STRICT_FCTIDZ";
1814 return "PPCISD::STRICT_FCTIWZ";
1816 return "PPCISD::STRICT_FCTIDUZ";
1818 return "PPCISD::STRICT_FCTIWUZ";
1820 return "PPCISD::STRICT_FCFID";
1822 return "PPCISD::STRICT_FCFIDU";
1824 return "PPCISD::STRICT_FCFIDS";
1826 return "PPCISD::STRICT_FCFIDUS";
1829 return "PPCISD::STORE_COND";
1831 return "PPCISD::SETBC";
1833 return "PPCISD::SETBCR";
1835 return "PPCISD::ADDC";
1837 return "PPCISD::ADDE";
1839 return "PPCISD::SUBC";
1841 return "PPCISD::SUBE";
1849 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1866 return CFP->getValueAPF().isZero();
1870 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1871 return CFP->getValueAPF().isZero();
1879 return Op < 0 ||
Op == Val;
1891 if (ShuffleKind == 0) {
1894 for (
unsigned i = 0; i != 16; ++i)
1897 }
else if (ShuffleKind == 2) {
1900 for (
unsigned i = 0; i != 16; ++i)
1903 }
else if (ShuffleKind == 1) {
1904 unsigned j = IsLE ? 0 : 1;
1905 for (
unsigned i = 0; i != 8; ++i)
1922 if (ShuffleKind == 0) {
1925 for (
unsigned i = 0; i != 16; i += 2)
1929 }
else if (ShuffleKind == 2) {
1932 for (
unsigned i = 0; i != 16; i += 2)
1936 }
else if (ShuffleKind == 1) {
1937 unsigned j = IsLE ? 0 : 2;
1938 for (
unsigned i = 0; i != 8; i += 2)
1959 if (!Subtarget.hasP8Vector())
1963 if (ShuffleKind == 0) {
1966 for (
unsigned i = 0; i != 16; i += 4)
1972 }
else if (ShuffleKind == 2) {
1975 for (
unsigned i = 0; i != 16; i += 4)
1981 }
else if (ShuffleKind == 1) {
1982 unsigned j = IsLE ? 0 : 4;
1983 for (
unsigned i = 0; i != 8; i += 4)
2000 unsigned LHSStart,
unsigned RHSStart) {
2001 if (
N->getValueType(0) != MVT::v16i8)
2003 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2004 "Unsupported merge size!");
2006 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2007 for (
unsigned j = 0; j != UnitSize; ++j) {
2009 LHSStart+j+i*UnitSize) ||
2011 RHSStart+j+i*UnitSize))
2026 if (ShuffleKind == 1)
2028 else if (ShuffleKind == 2)
2033 if (ShuffleKind == 1)
2035 else if (ShuffleKind == 0)
2051 if (ShuffleKind == 1)
2053 else if (ShuffleKind == 2)
2058 if (ShuffleKind == 1)
2060 else if (ShuffleKind == 0)
2110 unsigned RHSStartValue) {
2111 if (
N->getValueType(0) != MVT::v16i8)
2114 for (
unsigned i = 0; i < 2; ++i)
2115 for (
unsigned j = 0; j < 4; ++j)
2117 i*RHSStartValue+j+IndexOffset) ||
2119 i*RHSStartValue+j+IndexOffset+8))
2141 unsigned indexOffset = CheckEven ? 4 : 0;
2142 if (ShuffleKind == 1)
2144 else if (ShuffleKind == 2)
2150 unsigned indexOffset = CheckEven ? 0 : 4;
2151 if (ShuffleKind == 1)
2153 else if (ShuffleKind == 0)
2169 if (
N->getValueType(0) != MVT::v16i8)
2176 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2179 if (i == 16)
return -1;
2184 if (ShiftAmt < i)
return -1;
2189 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2191 for (++i; i != 16; ++i)
2194 }
else if (ShuffleKind == 1) {
2196 for (++i; i != 16; ++i)
2203 ShiftAmt = 16 - ShiftAmt;
2212 EVT VT =
N->getValueType(0);
2213 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2214 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2217 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2221 if (
N->getMaskElt(0) % EltSize != 0)
2226 unsigned ElementBase =
N->getMaskElt(0);
2229 if (ElementBase >= 16)
2234 for (
unsigned i = 1; i != EltSize; ++i)
2235 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2238 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2240 if (
N->getMaskElt(i) < 0) {
2241 for (
unsigned j = 1; j != EltSize; ++j)
2242 if (
N->getMaskElt(i + j) >= 0)
2245 for (
unsigned j = 0; j != EltSize; ++j)
2246 if (
N->getMaskElt(i + j) !=
N->getMaskElt(j))
2263 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2264 "Unexpected element width.");
2265 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2267 unsigned NumOfElem = 16 / Width;
2268 unsigned MaskVal[16];
2269 for (
unsigned i = 0; i < NumOfElem; ++i) {
2270 MaskVal[0] =
N->getMaskElt(i * Width);
2271 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2273 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2277 for (
unsigned int j = 1; j < Width; ++j) {
2278 MaskVal[j] =
N->getMaskElt(i * Width + j);
2279 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2289 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2294 unsigned M0 =
N->getMaskElt(0) / 4;
2295 unsigned M1 =
N->getMaskElt(4) / 4;
2296 unsigned M2 =
N->getMaskElt(8) / 4;
2297 unsigned M3 =
N->getMaskElt(12) / 4;
2298 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2299 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2304 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2305 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2306 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2307 InsertAtByte = IsLE ? 12 : 0;
2312 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2313 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2314 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2315 InsertAtByte = IsLE ? 8 : 4;
2320 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2321 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2322 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2323 InsertAtByte = IsLE ? 4 : 8;
2328 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2329 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2330 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2331 InsertAtByte = IsLE ? 0 : 12;
2338 if (
N->getOperand(1).isUndef()) {
2341 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2342 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2343 InsertAtByte = IsLE ? 12 : 0;
2346 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2347 InsertAtByte = IsLE ? 8 : 4;
2350 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2351 InsertAtByte = IsLE ? 4 : 8;
2354 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2355 InsertAtByte = IsLE ? 0 : 12;
2364 bool &Swap,
bool IsLE) {
2365 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2371 unsigned M0 =
N->getMaskElt(0) / 4;
2372 unsigned M1 =
N->getMaskElt(4) / 4;
2373 unsigned M2 =
N->getMaskElt(8) / 4;
2374 unsigned M3 =
N->getMaskElt(12) / 4;
2378 if (
N->getOperand(1).isUndef()) {
2379 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2380 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2383 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2389 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2393 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2398 ShiftElts = (8 -
M0) % 8;
2399 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2404 ShiftElts = (4 -
M0) % 4;
2409 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2414 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2426 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2431 for (
int i = 0; i < 16; i += Width)
2432 if (
N->getMaskElt(i) != i + Width - 1)
2463 bool &Swap,
bool IsLE) {
2464 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2470 unsigned M0 =
N->getMaskElt(0) / 8;
2471 unsigned M1 =
N->getMaskElt(8) / 8;
2472 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2476 if (
N->getOperand(1).isUndef()) {
2477 if ((
M0 |
M1) < 2) {
2478 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2486 if (
M0 > 1 &&
M1 < 2) {
2488 }
else if (M0 < 2 && M1 > 1) {
2496 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2499 if (M0 < 2 && M1 > 1) {
2501 }
else if (
M0 > 1 &&
M1 < 2) {
2509 DM = (
M0 << 1) + (
M1 & 1);
2524 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2529 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2545 unsigned EltSize = 16/
N->getNumOperands();
2546 if (EltSize < ByteSize) {
2547 unsigned Multiple = ByteSize/EltSize;
2549 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2552 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2553 if (
N->getOperand(i).isUndef())
continue;
2555 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2557 if (!UniquedVals[i&(Multiple-1)].
getNode())
2558 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2559 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2569 bool LeadingZero =
true;
2570 bool LeadingOnes =
true;
2571 for (
unsigned i = 0; i != Multiple-1; ++i) {
2572 if (!UniquedVals[i].
getNode())
continue;
2579 if (!UniquedVals[Multiple-1].
getNode())
2586 if (!UniquedVals[Multiple-1].
getNode())
2588 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2597 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2598 if (
N->getOperand(i).isUndef())
continue;
2600 OpVal =
N->getOperand(i);
2601 else if (OpVal !=
N->getOperand(i))
2607 unsigned ValSizeInBytes = EltSize;
2610 Value = CN->getZExtValue();
2612 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2613 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2619 if (ValSizeInBytes < ByteSize)
return SDValue();
2630 if (MaskVal == 0)
return SDValue();
2633 if (SignExtend32<5>(MaskVal) == MaskVal)
2647 if (!isa<ConstantSDNode>(
N))
2650 Imm = (int16_t)
N->getAsZExtVal();
2651 if (
N->getValueType(0) == MVT::i32)
2652 return Imm == (int32_t)
N->getAsZExtVal();
2654 return Imm == (int64_t)
N->getAsZExtVal();
2672 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2680 for (
SDNode *U :
N->users()) {
2681 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2682 if (Memop->getMemoryVT() == MVT::f64) {
2683 Base =
N.getOperand(0);
2684 Index =
N.getOperand(1);
2696 if (!isa<ConstantSDNode>(
N))
2699 Imm = (int64_t)cast<ConstantSDNode>(
N)->getSExtValue();
2700 return isInt<34>(Imm);
2727 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2732 Base =
N.getOperand(0);
2733 Index =
N.getOperand(1);
2735 }
else if (
N.getOpcode() ==
ISD::OR) {
2737 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2749 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2750 Base =
N.getOperand(0);
2751 Index =
N.getOperand(1);
2821 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2827 Base =
N.getOperand(0);
2830 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2832 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2833 "Cannot handle constant offsets yet!");
2834 Disp =
N.getOperand(1).getOperand(0);
2839 Base =
N.getOperand(0);
2842 }
else if (
N.getOpcode() ==
ISD::OR) {
2845 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2855 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2859 Base =
N.getOperand(0);
2872 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2875 CN->getValueType(0));
2880 if ((CN->getValueType(0) == MVT::i32 ||
2881 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2882 (!EncodingAlignment ||
2883 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2884 int Addr = (int)CN->getZExtValue();
2891 unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2912 if (
N.getValueType() != MVT::i64)
2925 Base =
N.getOperand(0);
2941 Base =
N.getOperand(0);
2974 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2975 Base =
N.getOperand(0);
2976 Index =
N.getOperand(1);
2988 Ty *PCRelCand = dyn_cast<Ty>(
N);
3000 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
3001 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
3002 isValidPCRelNode<JumpTableSDNode>(
N) ||
3003 isValidPCRelNode<BlockAddressSDNode>(
N))
3019 EVT MemVT = LD->getMemoryVT();
3026 if (!ST.hasP8Vector())
3031 if (!ST.hasP9Vector())
3043 if (
Use.getResNo() == 0 &&
3065 Ptr = LD->getBasePtr();
3066 VT = LD->getMemoryVT();
3067 Alignment = LD->getAlign();
3068 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3069 Ptr = ST->getBasePtr();
3070 VT = ST->getMemoryVT();
3071 Alignment = ST->getAlign();
3094 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3097 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3110 if (VT != MVT::i64) {
3115 if (Alignment <
Align(4))
3125 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3127 isa<ConstantSDNode>(
Offset))
3142 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3198 EVT PtrVT =
Op.getValueType();
3214 return getTOCEntry(DAG,
SDLoc(CP), GA);
3217 unsigned MOHiFlag, MOLoFlag;
3224 return getTOCEntry(DAG,
SDLoc(CP), GA);
3284 EVT PtrVT =
Op.getValueType();
3302 return getTOCEntry(DAG,
SDLoc(JT), GA);
3305 unsigned MOHiFlag, MOLoFlag;
3312 return getTOCEntry(DAG,
SDLoc(GA), GA);
3322 EVT PtrVT =
Op.getValueType();
3341 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3350 unsigned MOHiFlag, MOLoFlag;
3361 return LowerGlobalTLSAddressAIX(
Op, DAG);
3363 return LowerGlobalTLSAddressLinux(
Op, DAG);
3385 if (
I.getOpcode() == Instruction::Call)
3386 if (
const CallInst *CI = dyn_cast<const CallInst>(&
I))
3387 if (
Function *CF = CI->getCalledFunction())
3388 if (CF->isDeclaration() &&
3389 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3391 dyn_cast<GlobalValue>(
I.getOperand(0))) {
3397 unsigned TLSGVCnt = TLSGV.
size();
3407 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3422 bool Is64Bit = Subtarget.
isPPC64();
3426 if (Subtarget.hasAIXShLibTLSModelOpt())
3436 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3437 bool HasAIXSmallTLSGlobalAttr =
false;
3440 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3444 if (GVar->hasAttribute(
"aix-small-tls"))
3445 HasAIXSmallTLSGlobalAttr =
true;
3464 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3465 IsTLSLocalExecModel) {
3485 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3487 "currently only supported on AIX (64-bit mode).");
3493 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3497 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3499 "currently only supported on AIX (64-bit mode).");
3507 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3511 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3514 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3517 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3528 if (HasAIXSmallLocalDynamicTLS) {
3537 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3550 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3551 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3569 bool is64bit = Subtarget.
isPPC64();
3616 if (!
TM.isPositionIndependent())
3675 PtrVT, GOTPtr, TGA, TGA);
3677 PtrVT, TLSAddr, TGA);
3686 EVT PtrVT =
Op.getValueType();
3711 return getTOCEntry(DAG,
DL, GA);
3714 unsigned MOHiFlag, MOLoFlag;
3722 return getTOCEntry(DAG,
DL, GA);
3734 bool IsStrict =
Op->isStrictFPOpcode();
3736 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3740 EVT LHSVT =
LHS.getValueType();
3744 if (LHSVT == MVT::f128) {
3745 assert(!Subtarget.hasP9Vector() &&
3746 "SETCC for f128 is already legal under Power9!");
3757 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3759 if (
Op.getValueType() == MVT::v2i64) {
3762 if (
LHS.getValueType() == MVT::v2i64) {
3770 int ShuffV[] = {1, 0, 3, 2};
3775 dl, MVT::v4i32, Shuff, SetCC32));
3792 if (
C->isAllOnes() ||
C->isZero())
3802 EVT VT =
Op.getValueType();
3811 EVT VT =
Node->getValueType(0);
3815 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3825 if (VT == MVT::i64) {
3856 InChain = OverflowArea.
getValue(1);
3902 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3909 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3915 false,
true,
nullptr, std::nullopt,
3921 return Op.getOperand(0);
3930 "Expecting Inline ASM node.");
3940 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3946 unsigned NumVals =
Flags.getNumOperandRegisters();
3949 switch (
Flags.getKind()) {
3960 for (; NumVals; --NumVals, ++i) {
3961 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3962 if (Reg != PPC::LR && Reg != PPC::LR8)
3991 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
4001 const Value *TrampolineAddr =
4002 cast<SrcValueSDNode>(
Op.getOperand(4))->getValue();
4004 cast<Function>(cast<SrcValueSDNode>(
Op.getOperand(5))->getValue());
4012 PointerAlign, MMOFlags);
4014 OutChains[0] = DAG.
getStore(EPLoadChain, dl, LoadEntryPoint, Trmp,
4019 SDValue TOCFromDescriptorPtr =
4021 SDValue TOCReg = DAG.
getLoad(PtrVT, dl, Chain, TOCFromDescriptorPtr,
4023 PointerAlign, MMOFlags);
4024 SDValue TrampolineTOCPointer =
4028 DAG.
getStore(TOCLoadChain, dl, TOCReg, TrampolineTOCPointer,
4035 DAG.
getStore(Chain, dl, Nest, EnvPointer,
4043 bool isPPC64 = (PtrVT == MVT::i64);
4047 Args.emplace_back(Trmp, IntPtrTy);
4052 Args.emplace_back(FPtr, IntPtrTy);
4053 Args.emplace_back(Nest, IntPtrTy);
4057 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4061 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4062 return CallResult.second;
4076 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4077 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4112 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4121 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4136 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4139 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4141 nextOffset += FrameOffset;
4142 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4145 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4151static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4152 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4153 PPC::F11, PPC::F12, PPC::F13};
4158 unsigned PtrByteSize) {
4160 if (Flags.isByVal())
4161 ArgSize = Flags.getByValSize();
4165 if (!Flags.isInConsecutiveRegs())
4166 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4175 unsigned PtrByteSize) {
4176 Align Alignment(PtrByteSize);
4179 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4180 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4181 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4182 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4183 Alignment =
Align(16);
4186 if (Flags.isByVal()) {
4187 auto BVAlign = Flags.getNonZeroByValAlign();
4188 if (BVAlign > PtrByteSize) {
4189 if (BVAlign.value() % PtrByteSize != 0)
4191 "ByVal alignment is not a multiple of the pointer size");
4193 Alignment = BVAlign;
4198 if (Flags.isInConsecutiveRegs()) {
4202 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4216 unsigned PtrByteSize,
unsigned LinkageSize,
4217 unsigned ParamAreaSize,
unsigned &ArgOffset,
4218 unsigned &AvailableFPRs,
4219 unsigned &AvailableVRs) {
4220 bool UseMemory =
false;
4225 ArgOffset =
alignTo(ArgOffset, Alignment);
4228 if (ArgOffset >= LinkageSize + ParamAreaSize)
4233 if (Flags.isInConsecutiveRegsLast())
4234 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4237 if (ArgOffset > LinkageSize + ParamAreaSize)
4242 if (!Flags.isByVal()) {
4243 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4244 if (AvailableFPRs > 0) {
4248 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4249 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4250 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4251 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4252 if (AvailableVRs > 0) {
4264 unsigned NumBytes) {
4268SDValue PPCTargetLowering::LowerFormalArguments(
4273 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4276 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4279 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4283SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4325 const Align PtrAlign(4);
4334 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4337 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4350 RC = &PPC::GPRCRegClass;
4353 if (Subtarget.hasP8Vector())
4354 RC = &PPC::VSSRCRegClass;
4355 else if (Subtarget.hasSPE())
4356 RC = &PPC::GPRCRegClass;
4358 RC = &PPC::F4RCRegClass;
4361 if (Subtarget.hasVSX())
4362 RC = &PPC::VSFRCRegClass;
4363 else if (Subtarget.hasSPE())
4365 RC = &PPC::GPRCRegClass;
4367 RC = &PPC::F8RCRegClass;
4372 RC = &PPC::VRRCRegClass;
4375 RC = &PPC::VRRCRegClass;
4379 RC = &PPC::VRRCRegClass;
4386 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4387 assert(i + 1 < e &&
"No second half of double precision argument");
4399 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4400 if (ValVT == MVT::i1)
4415 ArgOffset += ArgSize - ObjSize;
4433 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4438 unsigned MinReservedArea = CCByValInfo.getStackSize();
4439 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4455 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4456 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4458 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4461 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4464 unsigned NumFPArgRegs = std::size(FPArgRegs);
4473 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4477 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4490 VReg = MF.
addLiveIn(GPArgReg, &PPC::GPRCRegClass);
4505 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4509 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4522 if (!MemOps.
empty())
4533 const SDLoc &dl)
const {
4537 else if (
Flags.isZExt())
4544SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4557 "fastcc not supported on varargs functions");
4563 unsigned PtrByteSize = 8;
4567 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4568 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4571 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4572 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4575 const unsigned Num_GPR_Regs = std::size(GPR);
4577 const unsigned Num_VR_Regs = std::size(VR);
4585 bool HasParameterArea = !isELFv2ABI || isVarArg;
4586 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4587 unsigned NumBytes = LinkageSize;
4588 unsigned AvailableFPRs = Num_FPR_Regs;
4589 unsigned AvailableVRs = Num_VR_Regs;
4591 if (
In.Flags.isNest())
4595 LinkageSize, ParamAreaSize, NumBytes,
4596 AvailableFPRs, AvailableVRs))
4597 HasParameterArea =
true;
4604 unsigned ArgOffset = LinkageSize;
4605 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4608 unsigned CurArgIdx = 0;
4609 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4611 bool needsLoad =
false;
4612 EVT ObjectVT =
Ins[ArgNo].VT;
4613 EVT OrigVT =
Ins[ArgNo].ArgVT;
4615 unsigned ArgSize = ObjSize;
4617 if (Ins[ArgNo].isOrigArg()) {
4618 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4619 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4624 unsigned CurArgOffset;
4626 auto ComputeArgOffset = [&]() {
4630 ArgOffset =
alignTo(ArgOffset, Alignment);
4631 CurArgOffset = ArgOffset;
4638 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4639 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4644 if (
Flags.isByVal()) {
4645 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4651 ObjSize =
Flags.getByValSize();
4652 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4674 if (HasParameterArea ||
4675 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4682 if (ObjSize < PtrByteSize) {
4686 if (!isLittleEndian) {
4692 if (GPR_idx != Num_GPR_Regs) {
4704 ArgOffset += PtrByteSize;
4713 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4714 if (GPR_idx == Num_GPR_Regs)
4725 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4733 ArgOffset += ArgSize;
4742 if (
Flags.isNest()) {
4747 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4748 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4756 if (GPR_idx != Num_GPR_Regs) {
4761 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4764 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4770 ArgSize = PtrByteSize;
4781 if (FPR_idx != Num_FPR_Regs) {
4784 if (ObjectVT == MVT::f32)
4786 Subtarget.hasP8Vector()
4787 ? &PPC::VSSRCRegClass
4788 : &PPC::F4RCRegClass);
4791 ? &PPC::VSFRCRegClass
4792 : &PPC::F8RCRegClass);
4807 if (ObjectVT == MVT::f32) {
4808 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4826 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4827 ArgOffset += ArgSize;
4828 if (
Flags.isInConsecutiveRegsLast())
4829 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4843 if (VR_idx != Num_VR_Regs) {
4860 if (ObjSize < ArgSize && !isLittleEndian)
4861 CurArgOffset += ArgSize - ObjSize;
4871 unsigned MinReservedArea;
4872 if (HasParameterArea)
4873 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4875 MinReservedArea = LinkageSize;
4892 int Depth = ArgOffset;
4901 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4902 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4914 if (!MemOps.
empty())
4923 unsigned ParamSize) {
4925 if (!isTailCall)
return 0;
4929 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4931 if (SPDiff < FI->getTailCallSPDelta())
4947 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4960 if (!TM.shouldAssumeDSOLocal(CalleeGV))
4966 const Function *
F = dyn_cast<Function>(CalleeGV);
4967 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4972 F = dyn_cast<Function>(GlobalObj);
5005 if (TM.getFunctionSections() || CalleeGV->
hasComdat() ||
5006 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
5008 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
5009 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
5021 const unsigned PtrByteSize = 8;
5025 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
5026 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
5029 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
5030 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
5033 const unsigned NumGPRs = std::size(GPR);
5034 const unsigned NumFPRs = 13;
5035 const unsigned NumVRs = std::size(VR);
5036 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5038 unsigned NumBytes = LinkageSize;
5039 unsigned AvailableFPRs = NumFPRs;
5040 unsigned AvailableVRs = NumVRs;
5043 if (Param.Flags.isNest())
continue;
5046 LinkageSize, ParamAreaSize, NumBytes,
5047 AvailableFPRs, AvailableVRs))
5058 auto CalleeArgEnd = CB.
arg_end();
5061 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5062 const Value* CalleeArg = *CalleeArgIter;
5063 const Value* CallerArg = &(*CallerArgIter);
5064 if (CalleeArg == CallerArg)
5072 isa<UndefValue>(CalleeArg))
5090 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5100bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5105 bool isCalleeExternalSymbol)
const {
5108 if (
DisableSCO && !TailCallOpt)
return false;
5111 if (isVarArg)
return false;
5187bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5221 if (!
C)
return nullptr;
5223 int Addr =
C->getZExtValue();
5224 if ((
Addr & 3) != 0 ||
5230 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5237struct TailCallArgumentInfo {
5242 TailCallArgumentInfo() =
default;
5252 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5253 SDValue Arg = TailCallArgs[i].Arg;
5254 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5255 int FI = TailCallArgs[i].FrameIdx;
5258 Chain, dl, Arg, FIN,
5267 int SPDiff,
const SDLoc &dl) {
5273 int SlotSize = Subtarget.
isPPC64() ? 8 : 4;
5274 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5276 NewRetAddrLoc,
true);
5279 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5289 int SPDiff,
unsigned ArgOffset,
5291 int Offset = ArgOffset + SPDiff;
5294 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5296 TailCallArgumentInfo
Info;
5298 Info.FrameIdxOp = FIN;
5306SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5311 LROpOut = getReturnAddrFrameIndex(DAG);
5330 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5338 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5362 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5372 if (!MemOpChains2.
empty())
5396SDValue PPCTargetLowering::LowerCallResult(
5404 CCRetInfo.AnalyzeCallResult(
5410 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5416 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5419 Chain =
Lo.getValue(1);
5420 InGlue =
Lo.getValue(2);
5424 Chain =
Hi.getValue(1);
5425 InGlue =
Hi.getValue(2);
5462 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5494 bool IsStrictFPCall =
false) {
5498 unsigned RetOpc = 0;
5523 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5529 if (IsStrictFPCall) {
5560 auto isLocalCallee = [&]() {
5565 !isa_and_nonnull<GlobalIFunc>(GV);
5576 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5586 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5589 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5592 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5593 return getAIXFuncEntryPointSymbolSDNode(GV);
5600 const char *SymName = S->getSymbol();
5606 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5607 return getAIXFuncEntryPointSymbolSDNode(
F);
5613 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5621 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5628 assert(Callee.getNode() &&
"What no callee?");
5634 "Expected a CALLSEQ_STARTSDNode.");
5651 SDValue MTCTROps[] = {Chain, Callee, Glue};
5652 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5693 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5712 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5713 Alignment, MMOFlags);
5720 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5727 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5739 "Nest parameter is not supported on AIX.");
5755 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5758 const bool IsPPC64 = Subtarget.
isPPC64();
5807 for (
const auto &[Reg,
N] : RegsToPass)
5825 assert(Mask &&
"Missing call preserved mask for calling convention");
5833SDValue PPCTargetLowering::FinishCall(
5848 if (!CFlags.IsIndirect)
5852 dl, CFlags.HasNest, Subtarget);
5862 if (CFlags.IsTailCall) {
5866 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5869 isa<ConstantSDNode>(Callee) ||
5871 "Expecting a global address, external symbol, absolute value, "
5872 "register or an indirect tail call when PC Relative calls are "
5876 "Unexpected call opcode for a tail call.");
5883 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5884 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5896 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5899 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5910 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5919 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5920 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5924bool PPCTargetLowering::isEligibleForTCO(
5929 bool isCalleeExternalSymbol)
const {
5934 return IsEligibleForTailCallOptimization_64SVR4(
5935 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5936 isCalleeExternalSymbol);
5938 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5961 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5963 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5966 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5980 isa<GlobalAddressSDNode>(Callee)) &&
5981 "Callee should be an llvm::Function object.");
5984 <<
"\nTCO callee: ");
5991 "site marked musttail");
5996 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5998 Callee = LowerGlobalAddress(Callee, DAG);
6001 CallConv, isTailCall, isVarArg, isPatchPoint,
6009 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6014 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6016 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
6020SDValue PPCTargetLowering::LowerCall_32SVR4(
6031 const bool IsVarArg = CFlags.IsVarArg;
6032 const bool IsTailCall = CFlags.IsTailCall;
6038 const Align PtrAlign(4);
6067 unsigned NumArgs = Outs.
size();
6069 for (
unsigned i = 0; i != NumArgs; ++i) {
6070 MVT ArgVT = Outs[i].VT;
6076 Outs[i].OrigTy, CCInfo);
6079 ArgFlags, Outs[i].OrigTy, CCInfo);
6084 errs() <<
"Call operand #" << i <<
" has unhandled type "
6100 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6107 unsigned NumBytes = CCByValInfo.getStackSize();
6121 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6132 bool seenFloatArg =
false;
6137 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6139 ++i, ++RealArgIdx) {
6141 SDValue Arg = OutVals[RealArgIdx];
6144 if (
Flags.isByVal()) {
6149 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6172 Chain = CallSeqStart = NewCallSeqStart;
6191 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6198 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6222 if (!MemOpChains.
empty())
6228 for (
const auto &[Reg,
N] : RegsToPass) {
6237 SDValue Ops[] = { Chain, InGlue };
6249 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6250 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6255SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6267 return NewCallSeqStart;
6270SDValue PPCTargetLowering::LowerCall_64SVR4(
6279 unsigned NumOps = Outs.
size();
6280 bool IsSibCall =
false;
6284 unsigned PtrByteSize = 8;
6299 assert(!(IsFastCall && CFlags.IsVarArg) &&
6300 "fastcc not supported on varargs functions");
6307 unsigned NumBytes = LinkageSize;
6308 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6311 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6312 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6315 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6316 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6319 const unsigned NumGPRs = std::size(GPR);
6321 const unsigned NumVRs = std::size(VR);
6327 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6328 if (!HasParameterArea) {
6329 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6330 unsigned AvailableFPRs = NumFPRs;
6331 unsigned AvailableVRs = NumVRs;
6332 unsigned NumBytesTmp = NumBytes;
6333 for (
unsigned i = 0; i != NumOps; ++i) {
6334 if (Outs[i].
Flags.isNest())
continue;
6336 PtrByteSize, LinkageSize, ParamAreaSize,
6337 NumBytesTmp, AvailableFPRs, AvailableVRs))
6338 HasParameterArea =
true;
6344 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6349 HasParameterArea =
false;
6352 for (
unsigned i = 0; i != NumOps; ++i) {
6354 EVT ArgVT = Outs[i].VT;
6355 EVT OrigVT = Outs[i].ArgVT;
6361 if (
Flags.isByVal()) {
6362 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6363 if (NumGPRsUsed > NumGPRs)
6364 HasParameterArea =
true;
6371 if (++NumGPRsUsed <= NumGPRs)
6381 if (++NumVRsUsed <= NumVRs)
6385 if (++NumVRsUsed <= NumVRs)
6390 if (++NumFPRsUsed <= NumFPRs)
6394 HasParameterArea =
true;
6401 NumBytes =
alignTo(NumBytes, Alignement);
6404 if (
Flags.isInConsecutiveRegsLast())
6405 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6408 unsigned NumBytesActuallyUsed = NumBytes;
6418 if (HasParameterArea)
6419 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6421 NumBytes = LinkageSize;
6436 if (CFlags.IsTailCall)
6448 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6459 unsigned ArgOffset = LinkageSize;
6465 for (
unsigned i = 0; i != NumOps; ++i) {
6468 EVT ArgVT = Outs[i].VT;
6469 EVT OrigVT = Outs[i].ArgVT;
6478 auto ComputePtrOff = [&]() {
6482 ArgOffset =
alignTo(ArgOffset, Alignment);
6493 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6494 GPR_idx = std::min(GPR_idx, NumGPRs);
6501 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6507 if (
Flags.isByVal()) {
6525 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6526 if (GPR_idx != NumGPRs) {
6530 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6532 ArgOffset += PtrByteSize;
6537 if (GPR_idx == NumGPRs &&
Size < 8) {
6539 if (!isLittleEndian) {
6544 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6547 ArgOffset += PtrByteSize;
6556 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6557 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6562 if (
Size < 8 && GPR_idx != NumGPRs) {
6572 if (!isLittleEndian) {
6576 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6584 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6587 ArgOffset += PtrByteSize;
6593 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6596 if (GPR_idx != NumGPRs) {
6597 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6603 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6604 ArgOffset += PtrByteSize;
6606 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6618 if (
Flags.isNest()) {
6620 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6627 if (GPR_idx != NumGPRs) {
6628 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6633 assert(HasParameterArea &&
6634 "Parameter area must exist to pass an argument in memory.");
6636 true, CFlags.IsTailCall,
false, MemOpChains,
6637 TailCallArguments, dl);
6639 ArgOffset += PtrByteSize;
6642 ArgOffset += PtrByteSize;
6655 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6656 bool NeededLoad =
false;
6659 if (FPR_idx != NumFPRs)
6660 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6663 if (!NeedGPROrStack)
6665 else if (GPR_idx != NumGPRs && !IsFastCall) {
6679 }
else if (!
Flags.isInConsecutiveRegs()) {
6685 }
else if (ArgOffset % PtrByteSize != 0) {
6689 if (!isLittleEndian)
6694 }
else if (
Flags.isInConsecutiveRegsLast()) {
6697 if (!isLittleEndian)
6707 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6715 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6720 assert(HasParameterArea &&
6721 "Parameter area must exist to pass an argument in memory.");
6723 true, CFlags.IsTailCall,
false, MemOpChains,
6724 TailCallArguments, dl);
6731 if (!IsFastCall || NeededLoad) {
6733 Flags.isInConsecutiveRegs()) ? 4 : 8;
6734 if (
Flags.isInConsecutiveRegsLast())
6735 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6755 if (CFlags.IsVarArg) {
6756 assert(HasParameterArea &&
6757 "Parameter area must exist if we have a varargs call.");
6763 if (VR_idx != NumVRs) {
6767 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6770 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6771 if (GPR_idx == NumGPRs)
6778 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6784 if (VR_idx != NumVRs) {
6785 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6790 assert(HasParameterArea &&
6791 "Parameter area must exist to pass an argument in memory.");
6793 true, CFlags.IsTailCall,
true, MemOpChains,
6794 TailCallArguments, dl);
6805 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6806 "mismatch in size of parameter area");
6807 (void)NumBytesActuallyUsed;
6809 if (!MemOpChains.
empty())
6815 if (CFlags.IsIndirect) {
6819 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6834 if (isELFv2ABI && !CFlags.IsPatchPoint)
6835 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6841 for (
const auto &[Reg,
N] : RegsToPass) {
6846 if (CFlags.IsTailCall && !IsSibCall)
6850 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6851 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6858 "Required alignment greater than stack alignment.");
6878 return RequiredAlign <= 8;
6883 return RequiredAlign <= 4;
6892 const bool IsPPC64 = Subtarget.
isPPC64();
6893 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6894 const Align PtrAlign(PtrSize);
6895 const Align StackAlign(16);
6898 if (ValVT == MVT::f128)
6902 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6903 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6905 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6906 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6909 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6910 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6911 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6925 if (ByValAlign > StackAlign)
6927 "16 are not supported.");
6930 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6934 if (ByValSize == 0) {
6942 while (NextReg != GPRs.
size() &&
6948 assert(Reg &&
"Alocating register unexpectedly failed.");
6953 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6974 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
7003 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
7005 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
7038 const unsigned VecSize = 16;
7039 const Align VecAlign(VecSize);
7059 while (NextRegIndex != GPRs.
size() &&
7064 assert(Reg &&
"Allocating register unexpectedly failed.");
7077 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7089 if (NextRegIndex == GPRs.
size()) {
7098 if (GPRs[NextRegIndex] == PPC::R9) {
7105 assert(FirstReg && SecondReg &&
7106 "Allocating R9 or R10 unexpectedly failed.");
7120 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7122 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7137 assert((IsPPC64 || SVT != MVT::i64) &&
7138 "i64 should have been split for 32-bit codegen.");
7146 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7148 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7150 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7158 return &PPC::VRRCRegClass;
7171 else if (Flags.isZExt())
7181 if (PPC::GPRCRegClass.
contains(Reg)) {
7182 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7183 "Reg must be a valid argument register!");
7184 return LASize + 4 * (Reg - PPC::R3);
7187 if (PPC::G8RCRegClass.
contains(Reg)) {
7188 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7189 "Reg must be a valid argument register!");
7190 return LASize + 8 * (Reg - PPC::X3);
7236SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7243 "Unexpected calling convention!");
7253 const bool IsPPC64 = Subtarget.
isPPC64();
7254 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7266 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7267 uint64_t SaveStackPos = CCInfo.getStackSize();
7269 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7280 bool ArgSignExt =
Ins[VA.
getValNo()].Flags.isSExt();
7292 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7294 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7306 unsigned StoreSize =
7308 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7311 auto HandleMemLoc = [&]() {
7314 assert((ValSize <= LocSize) &&
7315 "Object size is larger than size of MemLoc");
7318 if (LocSize > ValSize)
7319 CurArgOffset += LocSize - ValSize;
7321 const bool IsImmutable =
7361 assert(isVarArg &&
"Only use custom memloc for vararg.");
7364 const unsigned OriginalValNo = VA.
getValNo();
7365 (void)OriginalValNo;
7367 auto HandleCustomVecRegLoc = [&]() {
7368 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7369 "Missing custom RegLoc.");
7372 "Unexpected Val type for custom RegLoc.");
7374 "ValNo mismatch between custom MemLoc and RegLoc.");
7378 Subtarget.hasVSX()));
7385 HandleCustomVecRegLoc();
7386 HandleCustomVecRegLoc();
7390 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7392 "Only 2 custom RegLocs expected for 64-bit codegen.");
7393 HandleCustomVecRegLoc();
7394 HandleCustomVecRegLoc();
7438 const unsigned Size =
7450 if (
Flags.isByVal()) {
7456 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7465 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7467 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7480 CopyFrom.
getValue(1), dl, CopyFrom,
7490 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7493 "RegLocs should be for ByVal argument.");
7500 if (
Offset != StackSize) {
7502 "Expected MemLoc for remaining bytes.");
7503 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7517 Subtarget.hasVSX()));
7534 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7536 unsigned CallerReservedArea = std::max<unsigned>(
7537 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7543 CallerReservedArea =
7552 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7553 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7555 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7556 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7557 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7562 for (
unsigned GPRIndex =
7563 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7564 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7567 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7568 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7580 if (!MemOps.
empty())
7586SDValue PPCTargetLowering::LowerCall_AIX(
7599 "Unexpected calling convention!");
7601 if (CFlags.IsPatchPoint)
7608 CCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7616 const bool IsPPC64 = Subtarget.
isPPC64();
7618 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7619 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7620 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7628 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7629 const unsigned NumBytes = std::max<unsigned>(
7630 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7646 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7647 const unsigned ValNo = ArgLocs[
I].getValNo();
7651 if (
Flags.isByVal()) {
7652 const unsigned ByValSize =
Flags.getByValSize();
7660 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7669 unsigned LoadOffset = 0;
7672 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7675 LoadOffset += PtrByteSize;
7678 "Unexpected location for pass-by-value argument.");
7682 if (LoadOffset == ByValSize)
7686 assert(ArgLocs[
I].getValNo() == ValNo &&
7687 "Expected additional location for by-value argument.");
7689 if (ArgLocs[
I].isMemLoc()) {
7690 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7695 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7701 CallSeqStart, MemcpyFlags, DAG, dl);
7710 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7711 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7712 "Unexpected register residue for by-value argument.");
7714 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7718 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7728 "Unexpected load emitted during handling of pass-by-value "
7736 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7771 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7779 const unsigned OriginalValNo = VA.
getValNo();
7781 unsigned LoadOffset = 0;
7782 auto HandleCustomVecRegLoc = [&]() {
7783 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7784 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7785 "Expected custom RegLoc.");
7788 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7794 LoadOffset += PtrByteSize;
7800 HandleCustomVecRegLoc();
7801 HandleCustomVecRegLoc();
7803 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7804 ArgLocs[
I].getValNo() == OriginalValNo) {
7806 "Only 2 custom RegLocs expected for 64-bit codegen.");
7807 HandleCustomVecRegLoc();
7808 HandleCustomVecRegLoc();
7819 DAG.
getStore(Chain, dl, Arg, PtrOff,
7828 "Unexpected register handling for calling convention.");
7834 "Custom register handling only expected for VarArg.");
7852 "Unexpected custom register for argument!");
7873 if (!MemOpChains.
empty())
7878 if (CFlags.IsIndirect) {
7879 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7883 const unsigned TOCSaveOffset =
7899 for (
auto Reg : RegsToPass) {
7904 const int SPDiff = 0;
7905 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7906 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7916 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7917 return CCInfo.CheckReturn(
7932 CCInfo.AnalyzeReturn(Outs,
7941 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7945 SDValue Arg = OutVals[RealResIdx];
7960 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7983 RetOps.push_back(Glue);
7989PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7994 EVT IntVT =
Op.getValueType();
7998 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8000 SDValue Ops[2] = {Chain, FPSIdx};
8014 bool isPPC64 = Subtarget.
isPPC64();
8015 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
8035 bool isPPC64 = Subtarget.
isPPC64();
8056PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8058 bool isPPC64 = Subtarget.
isPPC64();
8092 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8093 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8104 bool isPPC64 = Subtarget.
isPPC64();
8116 Op.getOperand(0),
Op.getOperand(1));
8123 Op.getOperand(0),
Op.getOperand(1));
8127 if (
Op.getValueType().isVector())
8128 return LowerVectorLoad(
Op, DAG);
8130 assert(
Op.getValueType() == MVT::i1 &&
8131 "Custom lowering only for i1 loads");
8144 BasePtr, MVT::i8, MMO);
8152 if (
Op.getOperand(1).getValueType().isVector())
8153 return LowerVectorStore(
Op, DAG);
8155 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8156 "Custom lowering only for i1 stores");
8175 assert(
Op.getValueType() == MVT::i1 &&
8176 "Custom lowering only for i1 results");
8204 EVT TrgVT =
Op.getValueType();
8217 !llvm::has_single_bit<uint32_t>(
8228 if (SrcSize == 256) {
8239 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8247 for (
unsigned i = 0; i < TrgNumElts; ++i)
8250 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8254 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8267 EVT ResVT =
Op.getValueType();
8268 EVT CmpVT =
Op.getOperand(0).getValueType();
8270 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8276 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8293 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8325 if (
LHS.getValueType() == MVT::f32)
8338 if (
LHS.getValueType() == MVT::f32)
8347 if (
LHS.getValueType() == MVT::f32)
8361 if (
Cmp.getValueType() == MVT::f32)
8371 if (
Cmp.getValueType() == MVT::f32)
8377 if (
Cmp.getValueType() == MVT::f32)
8383 if (
Cmp.getValueType() == MVT::f32)
8389 if (
Cmp.getValueType() == MVT::f32)
8422 bool IsStrict =
Op->isStrictFPOpcode();
8428 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8431 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8433 MVT DestTy =
Op.getSimpleValueType();
8434 assert(Src.getValueType().isFloatingPoint() &&
8435 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8436 DestTy == MVT::i64) &&
8437 "Invalid FP_TO_INT types");
8438 if (Src.getValueType() == MVT::f32) {
8442 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8443 Chain = Src.getValue(1);
8447 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8457 assert((IsSigned || Subtarget.hasFPCVT()) &&
8458 "i64 FP_TO_UINT is supported only with FPCVT");
8461 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8473void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8475 const SDLoc &dl)
const {
8479 bool IsStrict =
Op->isStrictFPOpcode();
8482 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8483 (IsSigned || Subtarget.hasFPCVT());
8485 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8494 Alignment =
Align(4);
8497 SDValue Ops[] = { Chain, Tmp, FIPtr };
8499 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8501 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8505 if (
Op.getValueType() == MVT::i32 && !i32Stack &&
8515 RLI.Alignment = Alignment;
8523 const SDLoc &dl)
const {
8526 if (
Op->isStrictFPOpcode())
8533 const SDLoc &dl)
const {
8534 bool IsStrict =
Op->isStrictFPOpcode();
8537 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8538 EVT SrcVT = Src.getValueType();
8539 EVT DstVT =
Op.getValueType();
8542 if (SrcVT == MVT::f128)
8543 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8547 if (SrcVT == MVT::ppcf128) {
8548 if (DstVT == MVT::i32) {
8553 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8564 {Op.getOperand(0), Lo, Hi}, Flags);
8567 {Res.getValue(1), Res}, Flags);
8573 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8597 {Chain, Src, FltOfs}, Flags);
8601 {Chain, Val}, Flags);
8604 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8622 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8623 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8626 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8628 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8629 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8640bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8645 if (
Op->isStrictFPOpcode())
8650 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8654 Op.getOperand(0).getValueType())) {
8656 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8661 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8662 LD->isNonTemporal())
8664 if (
LD->getMemoryVT() != MemVT)
8674 RLI.Ptr =
LD->getBasePtr();
8675 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8677 "Non-pre-inc AM on PPC?");
8682 RLI.Chain =
LD->getChain();
8683 RLI.MPI =
LD->getPointerInfo();
8684 RLI.IsDereferenceable =
LD->isDereferenceable();
8685 RLI.IsInvariant =
LD->isInvariant();
8686 RLI.Alignment =
LD->getAlign();
8687 RLI.AAInfo =
LD->getAAInfo();
8688 RLI.Ranges =
LD->getRanges();
8690 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8697bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8698 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8705 if (!Subtarget.hasP9Vector() &&
8712 if (
Use.getResNo() != 0)
8735 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8739 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8742 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8743 if (
Op->isStrictFPOpcode()) {
8745 Chain =
Op.getOperand(0);
8747 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8749 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8757 const SDLoc &dl)
const {
8758 assert((
Op.getValueType() == MVT::f32 ||
8759 Op.getValueType() == MVT::f64) &&
8760 "Invalid floating point type as target of conversion");
8761 assert(Subtarget.hasFPCVT() &&
8762 "Int to FP conversions with direct moves require FPCVT");
8763 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8764 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8786 for (
unsigned i = 1; i < NumConcat; ++i)
8793 const SDLoc &dl)
const {
8794 bool IsStrict =
Op->isStrictFPOpcode();
8795 unsigned Opc =
Op.getOpcode();
8796 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8799 "Unexpected conversion type");
8800 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8801 "Supports conversions to v2f64/v4f32 only.");
8805 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8808 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8813 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8816 for (
unsigned i = 0; i < WideNumElts; ++i)
8819 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8820 int SaveElts = FourEltRes ? 4 : 2;
8822 for (
int i = 0; i < SaveElts; i++)
8823 ShuffV[i * Stride] = i;
8825 for (
int i = 1; i <= SaveElts; i++)
8826 ShuffV[i * Stride - 1] = i - 1;
8834 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8835 EVT ExtVT = Src.getValueType();
8836 if (Subtarget.hasP9Altivec())
8847 {Op.getOperand(0), Extend}, Flags);
8849 return DAG.
getNode(
Opc, dl,
Op.getValueType(), Extend);
8857 bool IsStrict =
Op->isStrictFPOpcode();
8858 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8863 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8865 EVT InVT = Src.getValueType();
8866 EVT OutVT =
Op.getValueType();
8869 return LowerINT_TO_FPVector(
Op, DAG, dl);
8872 if (
Op.getValueType() == MVT::f128)
8873 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8876 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8879 if (Src.getValueType() == MVT::i1) {
8891 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8892 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8893 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8895 assert((IsSigned || Subtarget.hasFPCVT()) &&
8896 "UINT_TO_FP is supported only with FPCVT");
8898 if (Src.getValueType() == MVT::i64) {
8910 if (
Op.getValueType() == MVT::f32 &&
8911 !Subtarget.hasFPCVT() &&
8952 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8953 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8954 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8957 }
else if (Subtarget.hasLFIWAX() &&
8958 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8961 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8962 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8965 Ops, MVT::i32, MMO);
8968 }
else if (Subtarget.hasFPCVT() &&
8969 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8972 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8973 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8976 Ops, MVT::i32, MMO);
8979 }
else if (((Subtarget.hasLFIWAX() &&
8981 (Subtarget.hasFPCVT() &&
8995 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8996 "Expected an i32 store");
9002 RLI.Alignment =
Align(4);
9006 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9007 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9010 dl, DAG.
getVTList(MVT::f64, MVT::Other),
9011 Ops, MVT::i32, MMO);
9012 Chain =
Bits.getValue(1);
9018 Chain =
FP.getValue(1);
9020 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9024 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9033 assert(Src.getValueType() == MVT::i32 &&
9034 "Unhandled INT_TO_FP type in custom expander!");
9044 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9047 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9056 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
9057 "Expected an i32 store");
9063 RLI.Alignment =
Align(4);
9068 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9069 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9071 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9074 if (ReusingLoad && RLI.ResChain) {
9079 "i32->FP without LFIWAX supported only on PPC64");
9088 Chain, dl, Ext64, FIdx,
9094 MVT::f64, dl, Chain, FIdx,
9102 Chain =
FP.getValue(1);
9103 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9107 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9123 if (
auto *CVal = dyn_cast<ConstantSDNode>(
Op.getOperand(1))) {
9125 assert(Mode < 4 &&
"Unsupported rounding mode!");
9126 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9127 if (Subtarget.isISA3_0())
9130 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9131 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9134 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9135 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9137 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9155 if (!Subtarget.isISA3_0()) {
9157 Chain =
MFFS.getValue(1);
9161 if (Subtarget.isISA3_0()) {
9166 PPC::RLDIMI, Dl, MVT::i64,
9171 NewFPSCR =
SDValue(InsertRN, 0);
9182 if (Subtarget.isISA3_0()) {
9190 PPC::RLWIMI, Dl, MVT::i32,
9191 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9192 DAG.getTargetConstant(30, Dl, MVT::i32),
9193 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9201 if (Subtarget.isISA3_0())
9207 PPC::MTFSF, Dl, MVT::Other,
9208 {DAG.
getConstant(255, Dl, MVT::i32,
true), NewFPSCR, Zero, Zero, Chain});
9235 EVT VT =
Op.getValueType();
9241 Chain =
MFFS.getValue(1);
9255 "Stack slot adjustment is valid only on big endian subtargets!");
9285 EVT VT =
Op.getValueType();
9289 VT ==
Op.getOperand(1).getValueType() &&
9309 SDValue OutOps[] = { OutLo, OutHi };
9314 EVT VT =
Op.getValueType();
9318 VT ==
Op.getOperand(1).getValueType() &&
9338 SDValue OutOps[] = { OutLo, OutHi };
9344 EVT VT =
Op.getValueType();
9347 VT ==
Op.getOperand(1).getValueType() &&
9367 SDValue OutOps[] = { OutLo, OutHi };
9374 EVT VT =
Op.getValueType();
9381 EVT AmtVT =
Z.getValueType();
9404 static const MVT VTys[] = {
9405 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9408 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9411 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9416 EVT CanonicalVT = VTys[SplatSize-1];
9429 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9430 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9439 EVT DestVT = MVT::Other) {
9440 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9449 EVT DestVT = MVT::Other) {
9452 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9464 for (
unsigned i = 0; i != 16; ++i)
9485 EVT VecVT = V->getValueType(0);
9486 bool RightType = VecVT == MVT::v2f64 ||
9487 (HasP8Vector && VecVT == MVT::v4f32) ||
9488 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9492 bool IsSplat =
true;
9493 bool IsLoad =
false;
9494 SDValue Op0 = V->getOperand(0);
9499 if (V->isConstant())
9501 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9502 if (V->getOperand(i).isUndef())
9506 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9508 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9510 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9512 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9516 if (V->getOperand(i) != Op0 ||
9517 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9520 return !(IsSplat && IsLoad);
9530 (
Op.getValueType() != MVT::f128))
9535 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9555 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9563 APFloat APFloatToConvert = ArgAPFloat;
9564 bool LosesInfo =
true;
9569 ArgAPFloat = APFloatToConvert;
9591 APFloat APFloatToConvert = ArgAPFloat;
9592 bool LosesInfo =
true;
9596 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9601 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9605 EVT Ty =
Op->getValueType(0);
9608 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9617 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9621 if (Ty == MVT::v2i64) {
9624 if (MemVT == MVT::i32) {
9636 bool IsLittleEndian) {
9642 APInt ConstValue(VTSize, 0);
9646 unsigned BitPos = 0;
9648 auto *CN = dyn_cast<ConstantSDNode>(OpVal);
9654 ConstValue.
insertBits(CN->getAPIntValue().zextOrTrunc(EltWidth),
9655 IsLittleEndian ? BitPos : VTSize - EltWidth - BitPos);
9659 for (
unsigned J = 0; J < 16; ++J) {
9661 if (ExtractValue != 0x00 && ExtractValue != 0xFF)
9663 if (ExtractValue == 0xFF)
9678 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9680 if (Subtarget.hasP10Vector()) {
9681 APInt BitMask(32, 0);
9687 BitMask != 0 && BitMask != 0xffff) {
9701 APInt APSplatBits, APSplatUndef;
9702 unsigned SplatBitSize;
9704 bool BVNIsConstantSplat =
9712 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9713 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9716 if ((
Op->getValueType(0) == MVT::v2f64) &&
9749 bool IsSplat64 =
false;
9751 int32_t SextVal = 0;
9752 if (BVNIsConstantSplat && SplatBitSize <= 64) {
9754 if (SplatBitSize <= 32) {
9756 }
else if (SplatBitSize == 64 && Subtarget.hasP8Altivec()) {
9757 int64_t Splat64Val =
static_cast<int64_t
>(SplatBits);
9758 bool P9Vector = Subtarget.hasP9Vector();
9759 int32_t
Hi = P9Vector ? 127 : 15;
9760 int32_t
Lo = P9Vector ? -128 : -16;
9761 IsSplat64 = Splat64Val >=
Lo && Splat64Val <=
Hi;
9762 SextVal =
static_cast<int32_t
>(SplatBits);
9766 if (!BVNIsConstantSplat || (SplatBitSize > 32 && !IsSplat64)) {
9773 const SDValue *InputLoad = &
Op.getOperand(0);
9778 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9779 unsigned ElementSize =
9782 assert(((ElementSize == 2 * MemorySize)
9786 "Unmatched element size and opcode!\n");
9791 unsigned NumUsesOfInputLD = 128 / ElementSize;
9793 if (BVInOp.isUndef())
9808 if (NumUsesOfInputLD == 1 &&
9811 Subtarget.hasLFIWAX()))
9820 Subtarget.isISA3_1() && ElementSize <= 16)
9823 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9825 Subtarget.hasVSX()) {
9832 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9833 LD->getMemoryVT(),
LD->getMemOperand());
9845 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9847 Subtarget.hasP8Vector()))
9853 unsigned SplatSize = SplatBitSize / 8;
9858 if (SplatBits == 0) {
9860 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9872 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9874 Op.getValueType(), DAG, dl);
9876 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9881 if (Subtarget.hasP9Vector() && SplatSize == 1)
9887 if (SextVal >= -16 && SextVal <= 15) {
9890 unsigned UseSize = SplatSize == 8 ? 4 : SplatSize;
9900 if (Subtarget.hasP9Vector() && SextVal >= -128 && SextVal <= 127) {
9905 switch (SplatSize) {
9909 IID = Intrinsic::ppc_altivec_vupklsb;
9912 IID = Intrinsic::ppc_altivec_vextsb2w;
9915 IID = Intrinsic::ppc_altivec_vextsb2d;
9921 assert(!IsSplat64 &&
"Unhandled 64-bit splat pattern");
9930 if (SextVal >= -32 && SextVal <= 31) {
9935 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9936 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9939 if (VT ==
Op.getValueType())
9948 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9962 static const signed char SplatCsts[] = {
9963 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9964 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9967 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9970 int i = SplatCsts[idx];
9974 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9977 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9979 static const unsigned IIDs[] = {
9980 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9981 Intrinsic::ppc_altivec_vslw
9988 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9990 static const unsigned IIDs[] = {
9991 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9992 Intrinsic::ppc_altivec_vsrw
9999 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
10000 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
10002 static const unsigned IIDs[] = {
10003 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
10004 Intrinsic::ppc_altivec_vrlw
10011 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
10017 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
10023 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
10038 unsigned OpNum = (PFEntry >> 26) & 0x0F;
10039 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
10040 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
10056 if (LHSID == (1*9+2)*9+3)
return LHS;
10057 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
10069 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
10070 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
10071 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
10072 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
10075 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
10076 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
10077 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
10078 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
10081 for (
unsigned i = 0; i != 16; ++i)
10082 ShufIdxs[i] = (i&3)+0;
10085 for (
unsigned i = 0; i != 16; ++i)
10086 ShufIdxs[i] = (i&3)+4;
10089 for (
unsigned i = 0; i != 16; ++i)
10090 ShufIdxs[i] = (i&3)+8;
10093 for (
unsigned i = 0; i != 16; ++i)
10094 ShufIdxs[i] = (i&3)+12;
10115 const unsigned BytesInVector = 16;
10120 unsigned ShiftElts = 0, InsertAtByte = 0;
10124 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
10125 0, 15, 14, 13, 12, 11, 10, 9};
10126 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10127 1, 2, 3, 4, 5, 6, 7, 8};
10130 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10142 bool FoundCandidate =
false;
10146 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10149 for (
unsigned i = 0; i < BytesInVector; ++i) {
10150 unsigned CurrentElement =
Mask[i];
10153 if (V2.
isUndef() && CurrentElement != VINSERTBSrcElem)
10156 bool OtherElementsInOrder =
true;
10159 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10166 (!V2.
isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10167 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10168 OtherElementsInOrder =
false;
10175 if (OtherElementsInOrder) {
10182 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10183 : BigEndianShifts[CurrentElement & 0xF];
10184 Swap = CurrentElement < BytesInVector;
10186 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10187 FoundCandidate =
true;
10192 if (!FoundCandidate)
10216 const unsigned NumHalfWords = 8;
10217 const unsigned BytesInVector = NumHalfWords * 2;
10226 unsigned ShiftElts = 0, InsertAtByte = 0;
10230 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10231 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10234 uint32_t OriginalOrderLow = 0x1234567;
10235 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10238 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10239 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10256 bool FoundCandidate =
false;
10259 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10260 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10270 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10271 TargetOrder = OriginalOrderLow;
10275 if (MaskOneElt == VINSERTHSrcElem &&
10276 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10277 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10278 FoundCandidate =
true;
10284 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10286 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10288 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10289 : BigEndianShifts[MaskOneElt & 0x7];
10290 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10291 Swap = MaskOneElt < NumHalfWords;
10292 FoundCandidate =
true;
10298 if (!FoundCandidate)
10333 auto ShuffleMask = SVN->
getMask();
10348 ShuffleMask = CommutedSV->
getMask();
10357 APInt APSplatValue, APSplatUndef;
10358 unsigned SplatBitSize;
10374 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10375 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10376 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10378 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10379 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10380 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10388 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10389 SplatVal |= (SplatVal << SplatBitSize);
10403 assert(
Op.getValueType() == MVT::v1i128 &&
10404 "Only set v1i128 as custom, other type shouldn't reach here!");
10409 if (SHLAmt % 8 == 0) {
10410 std::array<int, 16>
Mask;
10411 std::iota(
Mask.begin(),
Mask.end(), 0);
10412 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10441 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10442 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10445 SVOp = cast<ShuffleVectorSDNode>(
Op);
10446 V1 =
Op.getOperand(0);
10447 V2 =
Op.getOperand(1);
10449 EVT VT =
Op.getValueType();
10452 unsigned ShiftElts, InsertAtByte;
10458 bool IsPermutedLoad =
false;
10460 if (InputLoad && Subtarget.hasVSX() && V2.
isUndef() &&
10470 if (IsPermutedLoad) {
10471 assert((isLittleEndian || IsFourByte) &&
10472 "Unexpected size for permuted load on big endian target");
10473 SplatIdx += IsFourByte ? 2 : 1;
10474 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10475 "Splat of a value outside of the loaded memory");
10480 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10483 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10485 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10489 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10502 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10505 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10514 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10517 if (Subtarget.hasP9Vector() &&
10538 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10540 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10541 return SplatInsertNode;
10544 if (Subtarget.hasP9Altivec()) {
10546 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10549 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10553 if (Subtarget.hasVSX() &&
10566 if (Subtarget.hasVSX() &&
10579 if (Subtarget.hasP9Vector()) {
10599 if (Subtarget.hasVSX()) {
10620 if (V2.isUndef()) {
10633 (Subtarget.hasP8Altivec() && (
10644 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10654 (Subtarget.hasP8Altivec() && (
10665 unsigned PFIndexes[4];
10666 bool isFourElementShuffle =
true;
10667 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10669 unsigned EltNo = 8;
10670 for (
unsigned j = 0;
j != 4; ++
j) {
10671 if (PermMask[i * 4 + j] < 0)
10674 unsigned ByteSource = PermMask[i * 4 +
j];
10675 if ((ByteSource & 3) != j) {
10676 isFourElementShuffle =
false;
10681 EltNo = ByteSource / 4;
10682 }
else if (EltNo != ByteSource / 4) {
10683 isFourElementShuffle =
false;
10687 PFIndexes[i] = EltNo;
10695 if (isFourElementShuffle) {
10697 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10698 PFIndexes[2] * 9 + PFIndexes[3];
10701 unsigned Cost = (PFEntry >> 30);
10721 if (V2.isUndef()) V2 = V1;
10723 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10732 bool NeedSwap =
false;
10734 bool isPPC64 = Subtarget.
isPPC64();
10736 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10738 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10739 "XXPERM instead\n");
10748 NeedSwap = !NeedSwap;
10783 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10785 if (V1HasXXSWAPD) {
10788 else if (SrcElt < 16)
10791 if (V2HasXXSWAPD) {
10794 else if (SrcElt > 15)
10803 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10804 if (isLittleEndian)
10806 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10809 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10812 if (V1HasXXSWAPD) {
10816 if (V2HasXXSWAPD) {
10821 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10822 if (ValType != MVT::v2f64)
10828 ShufflesHandledWithVPERM++;
10833 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10835 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10838 dbgs() <<
"With the following permute control vector:\n";
10843 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10847 if (isLittleEndian)
10853 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10865 switch (IntrinsicID) {
10869 case Intrinsic::ppc_altivec_vcmpbfp_p:
10873 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10877 case Intrinsic::ppc_altivec_vcmpequb_p:
10881 case Intrinsic::ppc_altivec_vcmpequh_p:
10885 case Intrinsic::ppc_altivec_vcmpequw_p:
10889 case Intrinsic::ppc_altivec_vcmpequd_p:
10890 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10896 case Intrinsic::ppc_altivec_vcmpneb_p:
10897 case Intrinsic::ppc_altivec_vcmpneh_p:
10898 case Intrinsic::ppc_altivec_vcmpnew_p:
10899 case Intrinsic::ppc_altivec_vcmpnezb_p:
10900 case Intrinsic::ppc_altivec_vcmpnezh_p:
10901 case Intrinsic::ppc_altivec_vcmpnezw_p:
10902 if (Subtarget.hasP9Altivec()) {
10903 switch (IntrinsicID) {
10906 case Intrinsic::ppc_altivec_vcmpneb_p:
10909 case Intrinsic::ppc_altivec_vcmpneh_p:
10912 case Intrinsic::ppc_altivec_vcmpnew_p:
10915 case Intrinsic::ppc_altivec_vcmpnezb_p:
10918 case Intrinsic::ppc_altivec_vcmpnezh_p:
10921 case Intrinsic::ppc_altivec_vcmpnezw_p:
10929 case Intrinsic::ppc_altivec_vcmpgefp_p:
10933 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10937 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10941 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10945 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10949 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10950 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10956 case Intrinsic::ppc_altivec_vcmpgtub_p:
10960 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10964 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10968 case Intrinsic::ppc_altivec_vcmpgtud_p:
10969 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10976 case Intrinsic::ppc_altivec_vcmpequq:
10977 case Intrinsic::ppc_altivec_vcmpgtsq:
10978 case Intrinsic::ppc_altivec_vcmpgtuq:
10979 if (!Subtarget.isISA3_1())
10981 switch (IntrinsicID) {
10984 case Intrinsic::ppc_altivec_vcmpequq:
10987 case Intrinsic::ppc_altivec_vcmpgtsq:
10990 case Intrinsic::ppc_altivec_vcmpgtuq:
10997 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10998 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10999 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11000 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11001 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11002 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11003 if (Subtarget.hasVSX()) {
11004 switch (IntrinsicID) {
11005 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
11008 case Intrinsic::ppc_vsx_xvcmpgedp_p:
11011 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
11014 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
11017 case Intrinsic::ppc_vsx_xvcmpgesp_p:
11020 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
11030 case Intrinsic::ppc_altivec_vcmpbfp:
11033 case Intrinsic::ppc_altivec_vcmpeqfp:
11036 case Intrinsic::ppc_altivec_vcmpequb:
11039 case Intrinsic::ppc_altivec_vcmpequh:
11042 case Intrinsic::ppc_altivec_vcmpequw:
11045 case Intrinsic::ppc_altivec_vcmpequd:
11046 if (Subtarget.hasP8Altivec())
11051 case Intrinsic::ppc_altivec_vcmpneb:
11052 case Intrinsic::ppc_altivec_vcmpneh:
11053 case Intrinsic::ppc_altivec_vcmpnew:
11054 case Intrinsic::ppc_altivec_vcmpnezb:
11055 case Intrinsic::ppc_altivec_vcmpnezh:
11056 case Intrinsic::ppc_altivec_vcmpnezw:
11057 if (Subtarget.hasP9Altivec())
11058 switch (IntrinsicID) {
11061 case Intrinsic::ppc_altivec_vcmpneb:
11064 case Intrinsic::ppc_altivec_vcmpneh:
11067 case Intrinsic::ppc_altivec_vcmpnew:
11070 case Intrinsic::ppc_altivec_vcmpnezb:
11073 case Intrinsic::ppc_altivec_vcmpnezh:
11076 case Intrinsic::ppc_altivec_vcmpnezw:
11083 case Intrinsic::ppc_altivec_vcmpgefp:
11086 case Intrinsic::ppc_altivec_vcmpgtfp:
11089 case Intrinsic::ppc_altivec_vcmpgtsb:
11092 case Intrinsic::ppc_altivec_vcmpgtsh:
11095 case Intrinsic::ppc_altivec_vcmpgtsw:
11098 case Intrinsic::ppc_altivec_vcmpgtsd:
11099 if (Subtarget.hasP8Altivec())
11104 case Intrinsic::ppc_altivec_vcmpgtub:
11107 case Intrinsic::ppc_altivec_vcmpgtuh:
11110 case Intrinsic::ppc_altivec_vcmpgtuw:
11113 case Intrinsic::ppc_altivec_vcmpgtud:
11114 if (Subtarget.hasP8Altivec())
11119 case Intrinsic::ppc_altivec_vcmpequq_p:
11120 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11121 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11122 if (!Subtarget.isISA3_1())
11124 switch (IntrinsicID) {
11127 case Intrinsic::ppc_altivec_vcmpequq_p:
11130 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11133 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11147 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11151 switch (IntrinsicID) {
11152 case Intrinsic::thread_pointer:
11158 case Intrinsic::ppc_rldimi: {
11159 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
11163 return Op.getOperand(2);
11164 if (
Mask.isAllOnes())
11167 unsigned MB = 0, ME = 0;
11171 if (ME < 63 - SH) {
11174 }
else if (ME > 63 - SH) {
11180 {Op.getOperand(2), Src,
11181 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11182 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11186 case Intrinsic::ppc_rlwimi: {
11189 return Op.getOperand(2);
11190 if (
Mask.isAllOnes())
11193 unsigned MB = 0, ME = 0;
11197 PPC::RLWIMI, dl, MVT::i32,
11198 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11199 DAG.getTargetConstant(MB, dl, MVT::i32),
11200 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11204 case Intrinsic::ppc_rlwnm: {
11205 if (
Op.getConstantOperandVal(3) == 0)
11207 unsigned MB = 0, ME = 0;
11212 {Op.getOperand(1), Op.getOperand(2),
11213 DAG.getTargetConstant(MB, dl, MVT::i32),
11214 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11218 case Intrinsic::ppc_mma_disassemble_acc: {
11219 if (Subtarget.isISAFuture()) {
11220 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11258 case Intrinsic::ppc_vsx_disassemble_pair: {
11261 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11266 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11277 case Intrinsic::ppc_mma_build_dmr: {
11280 for (
int i = 1; i < 9; i += 2) {
11295 case Intrinsic::ppc_mma_dmxxextfdmr512: {
11296 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr512 requires ISA Future");
11297 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11298 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11299 "Specify P of 0 or 1 for lower or upper 512 bytes");
11300 unsigned HiLo =
Idx->getSExtValue();
11304 Opcode = PPC::DMXXEXTFDMR512;
11305 Subx = PPC::sub_wacc_lo;
11307 Opcode = PPC::DMXXEXTFDMR512_HI;
11308 Subx = PPC::sub_wacc_hi;
11311 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
11315 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11319 case Intrinsic::ppc_mma_dmxxextfdmr256: {
11320 assert(Subtarget.isISAFuture() &&
"dmxxextfdmr256 requires ISA Future");
11321 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11322 assert(
Idx && (
Idx->getSExtValue() >= 0 ||
Idx->getSExtValue() <= 3) &&
11323 "Specify a dmr row pair 0-3");
11324 unsigned IdxVal =
Idx->getSExtValue();
11328 Subx = PPC::sub_dmrrowp0;
11331 Subx = PPC::sub_dmrrowp1;
11334 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11337 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11341 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v256i1,
11347 DAG.
getMachineNode(PPC::DMXXEXTFDMR256, dl, MVT::v256i1, {Subreg, P}),
11351 case Intrinsic::ppc_mma_dmxxinstdmr512: {
11352 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr512 requires ISA Future");
11353 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(4));
11354 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11355 "Specify P of 0 or 1 for lower or upper 512 bytes");
11356 unsigned HiLo =
Idx->getSExtValue();
11360 Opcode = PPC::DMXXINSTDMR512;
11361 Subx = PPC::sub_wacc_lo;
11363 Opcode = PPC::DMXXINSTDMR512_HI;
11364 Subx = PPC::sub_wacc_hi;
11366 SDValue Ops[] = {
Op.getOperand(2),
Op.getOperand(3)};
11374 case Intrinsic::ppc_mma_dmxxinstdmr256: {
11375 assert(Subtarget.isISAFuture() &&
"dmxxinstdmr256 requires ISA Future");
11376 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(3));
11377 assert(
Idx && (
Idx->getSExtValue() >= 0 ||
Idx->getSExtValue() <= 3) &&
11378 "Specify a dmr row pair 0-3");
11379 unsigned IdxVal =
Idx->getSExtValue();
11383 Subx = PPC::sub_dmrrowp0;
11386 Subx = PPC::sub_dmrrowp1;
11389 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp0;
11392 Subx = PPC::sub_wacc_hi_then_sub_dmrrowp1;
11399 DAG.
getMachineNode(PPC::DMXXINSTDMR256, dl, MVT::v256i1, Ops), 0);
11401 Op.getOperand(1), DMRRowp,
SubReg),
11405 case Intrinsic::ppc_mma_xxmfacc:
11406 case Intrinsic::ppc_mma_xxmtacc: {
11408 if (!Subtarget.isISAFuture())
11419 case Intrinsic::ppc_unpack_longdouble: {
11420 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11421 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11422 "Argument of long double unpack must be 0 or 1!");
11425 Idx->getValueType(0)));
11428 case Intrinsic::ppc_compare_exp_lt:
11429 case Intrinsic::ppc_compare_exp_gt:
11430 case Intrinsic::ppc_compare_exp_eq:
11431 case Intrinsic::ppc_compare_exp_uo: {
11433 switch (IntrinsicID) {
11434 case Intrinsic::ppc_compare_exp_lt:
11437 case Intrinsic::ppc_compare_exp_gt:
11440 case Intrinsic::ppc_compare_exp_eq:
11443 case Intrinsic::ppc_compare_exp_uo:
11449 PPC::SELECT_CC_I4, dl, MVT::i32,
11450 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11451 Op.getOperand(1), Op.getOperand(2)),
11453 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11454 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11457 case Intrinsic::ppc_test_data_class: {
11458 EVT OpVT =
Op.getOperand(1).getValueType();
11459 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11460 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11464 PPC::SELECT_CC_I4, dl, MVT::i32,
11465 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11468 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11469 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11472 case Intrinsic::ppc_fnmsub: {
11473 EVT VT =
Op.getOperand(1).getValueType();
11474 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11480 Op.getOperand(2),
Op.getOperand(3));
11482 case Intrinsic::ppc_convert_f128_to_ppcf128:
11483 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11484 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11485 ? RTLIB::CONVERT_PPCF128_F128
11486 : RTLIB::CONVERT_F128_PPCF128;
11487 MakeLibCallOptions CallOptions;
11488 std::pair<SDValue, SDValue>
Result =
11489 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11493 case Intrinsic::ppc_maxfe:
11494 case Intrinsic::ppc_maxfl:
11495 case Intrinsic::ppc_maxfs:
11496 case Intrinsic::ppc_minfe:
11497 case Intrinsic::ppc_minfl:
11498 case Intrinsic::ppc_minfs: {
11499 EVT VT =
Op.getValueType();
11502 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11503 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11506 if (IntrinsicID == Intrinsic::ppc_minfe ||
11507 IntrinsicID == Intrinsic::ppc_minfl ||
11508 IntrinsicID == Intrinsic::ppc_minfs)
11530 Op.getOperand(1),
Op.getOperand(2),
11541 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11549 switch (
Op.getConstantOperandVal(1)) {
11554 Bitx = PPC::sub_eq;
11560 Bitx = PPC::sub_eq;
11566 Bitx = PPC::sub_lt;
11572 Bitx = PPC::sub_lt;
11578 if (Subtarget.isISA3_1()) {
11583 CR6Reg, SubRegIdx, GlueOp),
11585 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11611 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11613 switch (
Op.getConstantOperandVal(ArgStart)) {
11614 case Intrinsic::ppc_cfence: {
11615 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11616 SDValue Val =
Op.getOperand(ArgStart + 1);
11618 if (Ty == MVT::i128) {
11623 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11626 Opcode,
DL, MVT::Other,
11631 case Intrinsic::ppc_mma_disassemble_dmr: {
11652 int VectorIndex = 0;
11665 "Expecting an atomic compare-and-swap here.");
11667 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11668 EVT MemVT = AtomicNode->getMemoryVT();
11686 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11687 Ops.
push_back(AtomicNode->getOperand(i));
11699 EVT MemVT =
N->getMemoryVT();
11701 "Expect quadword atomic operations");
11703 unsigned Opc =
N->getOpcode();
11711 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11712 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11715 Ops, MemVT,
N->getMemOperand());
11722 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11732 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11742 N->getMemOperand());
11754 enum DataClassMask {
11756 DC_NEG_INF = 1 << 4,
11757 DC_POS_INF = 1 << 5,
11758 DC_NEG_ZERO = 1 << 2,
11759 DC_POS_ZERO = 1 << 3,
11760 DC_NEG_SUBNORM = 1,
11761 DC_POS_SUBNORM = 1 << 1,
11764 EVT VT =
Op.getValueType();
11766 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11767 : VT == MVT::f64 ? PPC::XSTSTDCDP
11778 return DAG.
getNOT(Dl, Rev, MVT::i1);
11785 TestOp, Dl, MVT::i32,
11787 DC_NEG_ZERO | DC_POS_ZERO |
11788 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11794 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11800 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11805 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11818 bool IsQuiet = Mask &
fcQNan;
11824 if (VT == MVT::f128) {
11828 QuietMask = 0x8000;
11829 }
else if (VT == MVT::f64) {
11841 QuietMask = 0x80000;
11842 }
else if (VT == MVT::f32) {
11844 QuietMask = 0x400000;
11860 unsigned NativeMask = 0;
11862 NativeMask |= DC_NAN;
11864 NativeMask |= DC_NEG_INF;
11866 NativeMask |= DC_POS_INF;
11868 NativeMask |= DC_NEG_ZERO;
11870 NativeMask |= DC_POS_ZERO;
11872 NativeMask |= DC_NEG_SUBNORM;
11874 NativeMask |= DC_POS_SUBNORM;
11877 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11879 TestOp, Dl, MVT::i32,
11888 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11890 uint64_t RHSC =
Op.getConstantOperandVal(1);
11893 if (
LHS.getValueType() == MVT::ppcf128) {
11909 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11910 if (isa<ConstantSDNode>(Op0) && EltSize <= 32) {
11911 int64_t
IntVal =
Op.getConstantOperandVal(0);
11912 if (IntVal >= -16 && IntVal <= 15)
11918 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11925 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11932 return Bits.getValue(0);
11953 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11960 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11974 "Should only be called for ISD::INSERT_VECTOR_ELT");
11978 EVT VT =
Op.getValueType();
11983 if (VT == MVT::v2f64 &&
C)
11986 if (Subtarget.hasP9Vector()) {
11995 if ((VT == MVT::v4f32) && (V2.
getValueType() == MVT::f32) &&
11996 (isa<LoadSDNode>(V2))) {
12001 BitcastLoad,
Op.getOperand(2));
12002 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
12006 if (Subtarget.isISA3_1()) {
12007 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
12011 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
12012 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
12022 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
12025 unsigned InsertAtElement =
C->getZExtValue();
12026 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
12028 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
12042 EVT VT =
Op.getValueType();
12043 bool IsV1024i1 = VT == MVT::v1024i1;
12044 bool IsV2048i1 = VT == MVT::v2048i1;
12048 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12050 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12051 "Dense Math support required.");
12052 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12061 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12070 DAG.
getVTList(MVT::v256i1, MVT::Other),
12071 LoadOps, MVT::v256i1, NewMMO);
12077 std::reverse(Loads.
begin(), Loads.
end());
12078 std::reverse(LoadChains.
begin(), LoadChains.
end());
12087 Loads[2], Loads[3]),
12091 const SDValue Ops[] = {RC,
Lo, LoSub,
Hi, HiSub};
12103 Loads[4], Loads[5]),
12106 Loads[6], Loads[7]),
12108 const SDValue Dmr1Ops[] = {RC, Dmr1Lo, LoSub, Dmr1Hi, HiSub};
12110 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v1024i1, Dmr1Ops), 0);
12116 const SDValue DmrPOps[] = {DmrPRC,
Value, Dmr0Sub, Dmr1Value, Dmr1Sub};
12119 DAG.
getMachineNode(PPC::REG_SEQUENCE, dl, MVT::v2048i1, DmrPOps), 0);
12132 Pairs[2], Pairs[3]),
12138 {RC, Lo, LoSub, Hi, HiSub}),
12148 EVT VT =
Op.getValueType();
12150 if (VT == MVT::v1024i1 || VT == MVT::v2048i1)
12151 return LowerDMFVectorLoad(
Op, DAG);
12153 if (VT != MVT::v256i1 && VT != MVT::v512i1)
12159 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
12160 "Type unsupported without MMA");
12161 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12162 "Type unsupported without paired vector support");
12167 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12169 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
12179 std::reverse(Loads.
begin(), Loads.
end());
12180 std::reverse(LoadChains.
begin(), LoadChains.
end());
12200 bool IsV1024i1 = VT == MVT::v1024i1;
12201 bool IsV2048i1 = VT == MVT::v2048i1;
12205 assert((IsV1024i1 || IsV2048i1) &&
"Unsupported type.");
12207 assert((Subtarget.hasMMA() && Subtarget.isISAFuture()) &&
12208 "Dense Math support required.");
12209 assert(Subtarget.pairedVectorMemops() &&
"Vector pair support required.");
12211 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12214 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12219 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1,
12227 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes,
Hi);
12233 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12239 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, MVT::v1024i1,
12245 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12250 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr0,
12255 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12260 TargetOpcode::EXTRACT_SUBREG, dl, MVT::v512i1, Dmr1,
12265 DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr0Lo);
12269 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr0Hi);
12272 ExtNode = DAG.
getMachineNode(PPC::DMXXEXTFDMR512, dl, ReturnTypes, Dmr1Lo);
12276 DAG.
getMachineNode(PPC::DMXXEXTFDMR512_HI, dl, ReturnTypes, Dmr1Hi);
12282 std::reverse(Values.
begin(), Values.
end());
12286 StoreChain, DAG.
getConstant(Intrinsic::ppc_vsx_stxvp, dl, MVT::i32),
12290 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12298 Ops[2] = Values[
Idx];
12300 MVT::v256i1, NewMMO);
12316 EVT StoreVT =
Value.getValueType();
12318 if (StoreVT == MVT::v1024i1 || StoreVT == MVT::v2048i1)
12319 return LowerDMFVectorStore(
Op, DAG);
12321 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
12327 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
12328 "Type unsupported without MMA");
12329 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
12330 "Type unsupported without paired vector support");
12333 unsigned NumVecs = 2;
12334 if (StoreVT == MVT::v512i1) {
12335 if (Subtarget.isISAFuture()) {
12336 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
12338 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
12341 Value2 =
SDValue(ExtNode, 1);
12346 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
12349 if (Subtarget.isISAFuture()) {
12359 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
12373 if (
Op.getValueType() == MVT::v4i32) {
12390 LHS, RHS, DAG, dl, MVT::v4i32);
12393 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
12398 }
else if (
Op.getValueType() == MVT::v16i8) {
12404 LHS, RHS, DAG, dl, MVT::v8i16);
12409 LHS, RHS, DAG, dl, MVT::v8i16);
12417 for (
unsigned i = 0; i != 8; ++i) {
12418 if (isLittleEndian) {
12420 Ops[i*2+1] = 2*i+16;
12423 Ops[i*2+1] = 2*i+1+16;
12426 if (isLittleEndian)
12436 bool IsStrict =
Op->isStrictFPOpcode();
12437 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
12438 !Subtarget.hasP9Vector())
12448 "Should only be called for ISD::FP_EXTEND");
12452 if (
Op.getValueType() != MVT::v2f64 ||
12453 Op.getOperand(0).getValueType() != MVT::v2f32)
12465 "Node should have 2 operands with second one being a constant!");
12477 int DWord =
Idx >> 1;
12500 LD->getMemoryVT(),
LD->getMemOperand());
12513 LD->getMemoryVT(),
LD->getMemOperand());
12525 if (STI.useCRBits())
12543 if (STI.useCRBits())
12552 EVT VT =
N->getValueType(0);
12553 EVT CarryType =
N->getValueType(1);
12554 unsigned Opc =
N->getOpcode();
12558 N->getOperand(0),
N->getOperand(1));
12571 unsigned Opc =
N->getOpcode();
12572 EVT VT =
N->getValueType(0);
12573 EVT CarryType =
N->getValueType(1);
12574 SDValue CarryOp =
N->getOperand(2);
12582 Op.getOperand(0),
Op.getOperand(1), CarryOp);
12596 EVT VT =
Op.getNode()->getValueType(0);
12618 switch (
Op.getOpcode()) {
12638 return LowerSSUBO(
Op, DAG);
12650 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12671 return LowerSET_ROUNDING(
Op, DAG);
12678 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12679 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12691 return LowerFP_ROUND(
Op, DAG);
12704 return LowerINTRINSIC_VOID(
Op, DAG);
12706 return LowerBSWAP(
Op, DAG);
12708 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12710 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12712 return LowerIS_FPCLASS(
Op, DAG);
12715 return LowerADDSUBO(
Op, DAG);
12718 return LowerADDSUBO_CARRY(
Op, DAG);
12726 switch (
N->getOpcode()) {
12728 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12745 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12748 assert(
N->getValueType(0) == MVT::i1 &&
12749 "Unexpected result type for CTR decrement intrinsic");
12751 N->getValueType(0));
12761 switch (
N->getConstantOperandVal(0)) {
12762 case Intrinsic::ppc_pack_longdouble:
12764 N->getOperand(2),
N->getOperand(1)));
12766 case Intrinsic::ppc_maxfe:
12767 case Intrinsic::ppc_minfe:
12768 case Intrinsic::ppc_fnmsub:
12769 case Intrinsic::ppc_convert_f128_to_ppcf128:
12779 EVT VT =
N->getValueType(0);
12781 if (VT == MVT::i64) {
12794 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12798 Results.push_back(LoweredValue);
12799 if (
N->isStrictFPOpcode())
12804 if (!
N->getValueType(0).isVector())
12845 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12846 "Only 8/16/32/64-bit atomic loads supported");
12852 IntID = Intrinsic::ppc_lbarx;
12853 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12856 IntID = Intrinsic::ppc_lharx;
12857 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12860 IntID = Intrinsic::ppc_lwarx;
12863 IntID = Intrinsic::ppc_ldarx;
12880 assert((SZ == 8 || SZ == 16 || SZ == 32 || SZ == 64) &&
12881 "Only 8/16/32/64-bit atomic loads supported");
12887 IntID = Intrinsic::ppc_stbcx;
12888 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12891 IntID = Intrinsic::ppc_sthcx;
12892 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
12895 IntID = Intrinsic::ppc_stwcx;
12898 IntID = Intrinsic::ppc_stdcx;
12902 if (SZ == 8 || SZ == 16)
12929 if (isa<LoadInst>(Inst))
12940 unsigned AtomicSize,
12941 unsigned BinOpcode,
12942 unsigned CmpOpcode,
12943 unsigned CmpPred)
const {
12947 auto LoadMnemonic = PPC::LDARX;
12948 auto StoreMnemonic = PPC::STDCX;
12949 switch (AtomicSize) {
12953 LoadMnemonic = PPC::LBARX;
12954 StoreMnemonic = PPC::STBCX;
12955 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12958 LoadMnemonic = PPC::LHARX;
12959 StoreMnemonic = PPC::STHCX;
12960 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12963 LoadMnemonic = PPC::LWARX;
12964 StoreMnemonic = PPC::STWCX;
12967 LoadMnemonic = PPC::LDARX;
12968 StoreMnemonic = PPC::STDCX;
12984 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12986 F->insert(It, loopMBB);
12988 F->insert(It, loop2MBB);
12989 F->insert(It, exitMBB);
12995 Register TmpReg = (!BinOpcode) ? incr :
12997 : &PPC::GPRCRegClass);
13022 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
13029 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
13031 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
13059 switch(
MI.getOpcode()) {
13063 return TII->isSignExtended(
MI.getOperand(1).getReg(),
13064 &
MI.getMF()->getRegInfo());
13088 case PPC::EXTSB8_32_64:
13089 case PPC::EXTSB8_rec:
13090 case PPC::EXTSB_rec:
13093 case PPC::EXTSH8_32_64:
13094 case PPC::EXTSH8_rec:
13095 case PPC::EXTSH_rec:
13097 case PPC::EXTSWSLI:
13098 case PPC::EXTSWSLI_32_64:
13099 case PPC::EXTSWSLI_32_64_rec:
13100 case PPC::EXTSWSLI_rec:
13101 case PPC::EXTSW_32:
13102 case PPC::EXTSW_32_64:
13103 case PPC::EXTSW_32_64_rec:
13104 case PPC::EXTSW_rec:
13107 case PPC::SRAWI_rec:
13108 case PPC::SRAW_rec:
13117 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
13127 bool IsSignExtended =
13130 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
13132 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
13133 .
addReg(
MI.getOperand(3).getReg());
13134 MI.getOperand(3).setReg(ValueReg);
13138 if (Subtarget.hasPartwordAtomics())
13146 bool is64bit = Subtarget.
isPPC64();
13148 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13159 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
13161 F->insert(It, loopMBB);
13163 F->insert(It, loop2MBB);
13164 F->insert(It, exitMBB);
13170 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13215 if (ptrA != ZeroReg) {
13217 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13225 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13226 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13229 .
addImm(is8bit ? 28 : 27);
13230 if (!isLittleEndian)
13231 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13233 .
addImm(is8bit ? 24 : 16);
13235 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13240 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13250 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13254 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13259 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13263 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
13266 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13278 unsigned ValueReg = SReg;
13279 unsigned CmpReg = Incr2Reg;
13280 if (CmpOpcode == PPC::CMPW) {
13282 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
13286 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
13288 ValueReg = ValueSReg;
13320 .
addImm(is8bit ? 24 : 16)
13341 Register DstReg =
MI.getOperand(0).getReg();
13343 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
13344 Register mainDstReg =
MRI.createVirtualRegister(RC);
13345 Register restoreDstReg =
MRI.createVirtualRegister(RC);
13348 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13349 "Invalid Pointer Size!");
13397 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
13398 Register BufReg =
MI.getOperand(1).getReg();
13413 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
13415 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
13418 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
13441 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
13462 TII->get(PPC::PHI), DstReg)
13466 MI.eraseFromParent();
13480 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
13481 "Invalid Pointer Size!");
13484 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13487 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
13488 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
13502 Register BufReg =
MI.getOperand(0).getReg();
13507 if (PVT == MVT::i64) {
13519 if (PVT == MVT::i64) {
13531 if (PVT == MVT::i64) {
13543 if (PVT == MVT::i64) {
13555 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
13565 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
13568 MI.eraseFromParent();
13584 "Unexpected stack alignment");
13588 unsigned StackProbeSize =
13591 StackProbeSize &= ~(StackAlign - 1);
13592 return StackProbeSize ? StackProbeSize : StackAlign;
13604 const bool isPPC64 = Subtarget.
isPPC64();
13636 MF->
insert(MBBIter, TestMBB);
13637 MF->
insert(MBBIter, BlockMBB);
13638 MF->
insert(MBBIter, TailMBB);
13643 Register DstReg =
MI.getOperand(0).getReg();
13644 Register NegSizeReg =
MI.getOperand(1).getReg();
13646 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13647 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13648 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13654 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13656 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13662 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13663 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13665 .
addDef(ActualNegSizeReg)
13667 .
add(
MI.getOperand(2))
13668 .
add(
MI.getOperand(3));
13674 .
addReg(ActualNegSizeReg);
13677 int64_t NegProbeSize = -(int64_t)ProbeSize;
13678 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
13679 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13680 if (!isInt<16>(NegProbeSize)) {
13681 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13683 .
addImm(NegProbeSize >> 16);
13687 .
addImm(NegProbeSize & 0xFFFF);
13694 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13696 .
addReg(ActualNegSizeReg)
13698 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13702 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13705 .
addReg(ActualNegSizeReg);
13714 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13715 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13740 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13742 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13743 MaxCallFrameSizeReg)
13744 .
add(
MI.getOperand(2))
13745 .
add(
MI.getOperand(3));
13746 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13748 .
addReg(MaxCallFrameSizeReg);
13757 MI.eraseFromParent();
13759 ++NumDynamicAllocaProbed;
13764 switch (
MI.getOpcode()) {
13765 case PPC::SELECT_CC_I4:
13766 case PPC::SELECT_CC_I8:
13767 case PPC::SELECT_CC_F4:
13768 case PPC::SELECT_CC_F8:
13769 case PPC::SELECT_CC_F16:
13770 case PPC::SELECT_CC_VRRC:
13771 case PPC::SELECT_CC_VSFRC:
13772 case PPC::SELECT_CC_VSSRC:
13773 case PPC::SELECT_CC_VSRC:
13774 case PPC::SELECT_CC_SPE4:
13775 case PPC::SELECT_CC_SPE:
13783 switch (
MI.getOpcode()) {
13784 case PPC::SELECT_I4:
13785 case PPC::SELECT_I8:
13786 case PPC::SELECT_F4:
13787 case PPC::SELECT_F8:
13788 case PPC::SELECT_F16:
13789 case PPC::SELECT_SPE:
13790 case PPC::SELECT_SPE4:
13791 case PPC::SELECT_VRRC:
13792 case PPC::SELECT_VSFRC:
13793 case PPC::SELECT_VSSRC:
13794 case PPC::SELECT_VSRC:
13804 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13805 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13807 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13820 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13821 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13823 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13824 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13838 if (Subtarget.hasISEL() &&
13839 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13840 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13841 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13843 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13844 MI.getOpcode() == PPC::SELECT_CC_I8)
13845 Cond.push_back(
MI.getOperand(4));
13848 Cond.push_back(
MI.getOperand(1));
13851 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13852 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13868 F->insert(It, copy0MBB);
13869 F->insert(It, sinkMBB);
13878 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13893 .
addReg(
MI.getOperand(1).getReg())
13896 unsigned SelectPred =
MI.getOperand(4).getImm();
13899 .
addReg(
MI.getOperand(1).getReg())
13916 .
addReg(
MI.getOperand(3).getReg())
13918 .
addReg(
MI.getOperand(2).getReg())
13920 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13936 F->insert(It, readMBB);
13937 F->insert(It, sinkMBB);
13958 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13968 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13970 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13972 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13974 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13977 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13979 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13981 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13983 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13986 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13988 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13990 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13992 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13995 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13997 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13999 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
14001 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
14004 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
14006 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
14008 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
14010 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
14013 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
14015 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
14017 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
14019 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
14022 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
14024 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
14026 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
14028 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
14031 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
14033 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
14035 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
14037 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
14040 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
14042 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
14044 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
14046 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
14049 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
14051 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
14053 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
14055 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
14058 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
14060 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
14062 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
14064 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
14066 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
14067 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
14068 (Subtarget.hasPartwordAtomics() &&
14069 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
14070 (Subtarget.hasPartwordAtomics() &&
14071 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
14072 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
14074 auto LoadMnemonic = PPC::LDARX;
14075 auto StoreMnemonic = PPC::STDCX;
14076 switch (
MI.getOpcode()) {
14079 case PPC::ATOMIC_CMP_SWAP_I8:
14080 LoadMnemonic = PPC::LBARX;
14081 StoreMnemonic = PPC::STBCX;
14082 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14084 case PPC::ATOMIC_CMP_SWAP_I16:
14085 LoadMnemonic = PPC::LHARX;
14086 StoreMnemonic = PPC::STHCX;
14087 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
14089 case PPC::ATOMIC_CMP_SWAP_I32:
14090 LoadMnemonic = PPC::LWARX;
14091 StoreMnemonic = PPC::STWCX;
14093 case PPC::ATOMIC_CMP_SWAP_I64:
14094 LoadMnemonic = PPC::LDARX;
14095 StoreMnemonic = PPC::STDCX;
14103 Register oldval =
MI.getOperand(3).getReg();
14104 Register newval =
MI.getOperand(4).getReg();
14110 F->insert(It, loop1MBB);
14111 F->insert(It, loop2MBB);
14112 F->insert(It, exitMBB);
14133 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
14159 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
14160 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
14164 bool is64bit = Subtarget.
isPPC64();
14166 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
14171 Register oldval =
MI.getOperand(3).getReg();
14172 Register newval =
MI.getOperand(4).getReg();
14178 F->insert(It, loop1MBB);
14179 F->insert(It, loop2MBB);
14180 F->insert(It, exitMBB);
14187 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
14206 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
14238 if (ptrA != ZeroReg) {
14240 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
14249 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
14250 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
14253 .
addImm(is8bit ? 28 : 27);
14254 if (!isLittleEndian)
14255 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
14257 .
addImm(is8bit ? 24 : 16);
14259 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
14264 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
14269 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
14272 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
14279 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
14283 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
14286 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
14289 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
14294 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
14311 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
14335 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
14360 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
14368 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14369 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
14370 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14371 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
14372 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
14373 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
14376 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
14377 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
14381 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
14385 .
addReg(
MI.getOperand(1).getReg())
14388 MI.getOperand(0).getReg())
14389 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
14390 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
14396 MI.getOperand(0).getReg())
14398 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
14400 unsigned Imm =
MI.getOperand(1).getImm();
14403 MI.getOperand(0).getReg())
14405 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
14407 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14410 if (
MRI.use_empty(OldFPSCRReg))
14411 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14413 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14424 unsigned Mode =
MI.getOperand(1).getImm();
14425 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
14429 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
14432 }
else if (
MI.getOpcode() == PPC::SETRND) {
14440 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
14441 if (Subtarget.hasDirectMove()) {
14442 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
14446 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
14449 if (RC == &PPC::F8RCRegClass) {
14452 "Unsupported RegClass.");
14454 StoreOp = PPC::STFD;
14459 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
14460 "Unsupported RegClass.");
14493 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14496 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14510 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
14518 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
14519 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
14525 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
14532 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
14541 }
else if (
MI.getOpcode() == PPC::SETFLM) {
14545 Register OldFPSCRReg =
MI.getOperand(0).getReg();
14546 if (
MRI.use_empty(OldFPSCRReg))
14547 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
14549 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
14552 Register NewFPSCRReg =
MI.getOperand(1).getReg();
14558 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
14559 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
14561 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
14568 .
addUse(Src, 0, PPC::sub_gp8_x1);
14571 .
addUse(Src, 0, PPC::sub_gp8_x0);
14572 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
14573 MI.getOpcode() == PPC::STQX_PSEUDO) {
14579 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
14585 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
14586 :
TII->get(PPC::STQ))
14594 MI.eraseFromParent();
14607 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14610 return RefinementSteps;
14616 EVT VT =
Op.getValueType();
14619 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14643PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14646 EVT VT =
Op.getValueType();
14647 if (VT != MVT::f64 &&
14648 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14655 int Enabled,
int &RefinementSteps,
14656 bool &UseOneConstNR,
14657 bool Reciprocal)
const {
14659 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14660 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14661 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14662 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14668 UseOneConstNR = !Subtarget.needsTwoConstNR();
14676 int &RefinementSteps)
const {
14678 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14679 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14680 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14681 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14689unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
14727 unsigned Bytes,
int Dist,
14737 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
14738 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
14741 if (FS != BFS || FS != (
int)Bytes)
return false;
14745 SDValue Base1 = Loc, Base2 = BaseLoc;
14746 int64_t Offset1 = 0, Offset2 = 0;
14749 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14759 if (isGA1 && isGA2 && GV1 == GV2)
14760 return Offset1 == (Offset2 + Dist*Bytes);
14767 unsigned Bytes,
int Dist,
14770 EVT VT = LS->getMemoryVT();
14771 SDValue Loc = LS->getBasePtr();
14777 switch (
N->getConstantOperandVal(1)) {
14778 default:
return false;
14779 case Intrinsic::ppc_altivec_lvx:
14780 case Intrinsic::ppc_altivec_lvxl:
14781 case Intrinsic::ppc_vsx_lxvw4x:
14782 case Intrinsic::ppc_vsx_lxvw4x_be:
14785 case Intrinsic::ppc_vsx_lxvd2x:
14786 case Intrinsic::ppc_vsx_lxvd2x_be:
14789 case Intrinsic::ppc_altivec_lvebx:
14792 case Intrinsic::ppc_altivec_lvehx:
14795 case Intrinsic::ppc_altivec_lvewx:
14805 switch (
N->getConstantOperandVal(1)) {
14806 default:
return false;
14807 case Intrinsic::ppc_altivec_stvx:
14808 case Intrinsic::ppc_altivec_stvxl:
14809 case Intrinsic::ppc_vsx_stxvw4x:
14812 case Intrinsic::ppc_vsx_stxvd2x:
14815 case Intrinsic::ppc_vsx_stxvw4x_be:
14818 case Intrinsic::ppc_vsx_stxvd2x_be:
14821 case Intrinsic::ppc_altivec_stvebx:
14824 case Intrinsic::ppc_altivec_stvehx:
14827 case Intrinsic::ppc_altivec_stvewx:
14844 SDValue Chain = LD->getChain();
14845 EVT VT = LD->getMemoryVT();
14854 while (!Queue.empty()) {
14855 SDNode *ChainNext = Queue.pop_back_val();
14856 if (!Visited.
insert(ChainNext).second)
14859 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
14863 if (!Visited.
count(ChainLD->getChain().getNode()))
14864 Queue.push_back(ChainLD->getChain().getNode());
14866 for (
const SDUse &O : ChainNext->
ops())
14867 if (!Visited.
count(O.getNode()))
14868 Queue.push_back(O.getNode());
14870 LoadRoots.
insert(ChainNext);
14881 for (
SDNode *
I : LoadRoots) {
14882 Queue.push_back(
I);
14884 while (!Queue.empty()) {
14885 SDNode *LoadRoot = Queue.pop_back_val();
14886 if (!Visited.
insert(LoadRoot).second)
14889 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
14894 if (((isa<MemSDNode>(U) &&
14895 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
14898 Queue.push_back(U);
14931 auto Final = Shifted;
14942 DAGCombinerInfo &DCI)
const {
14950 if (!DCI.isAfterLegalizeDAG())
14955 for (
const SDNode *U :
N->users())
14959 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
14960 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14964 if (OpSize <
Size) {
14982 DAGCombinerInfo &DCI)
const {
14986 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14997 N->getValueType(0) != MVT::i1)
15000 if (
N->getOperand(0).getValueType() != MVT::i32 &&
15001 N->getOperand(0).getValueType() != MVT::i64)
15009 cast<CondCodeSDNode>(
N->getOperand(
15011 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
15022 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
15045 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15046 N->getOperand(0).getOpcode() !=
ISD::OR &&
15047 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15057 N->getOperand(1).getOpcode() !=
ISD::AND &&
15058 N->getOperand(1).getOpcode() !=
ISD::OR &&
15059 N->getOperand(1).getOpcode() !=
ISD::XOR &&
15072 for (
unsigned i = 0; i < 2; ++i) {
15076 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
15077 isa<ConstantSDNode>(
N->getOperand(i)))
15088 while (!BinOps.
empty()) {
15096 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15130 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15131 if (isa<ConstantSDNode>(Inputs[i]))
15154 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15176 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15179 if (isa<ConstantSDNode>(Inputs[i]))
15185 std::list<HandleSDNode> PromOpHandles;
15186 for (
auto &PromOp : PromOps)
15187 PromOpHandles.emplace_back(PromOp);
15194 while (!PromOpHandles.empty()) {
15196 PromOpHandles.pop_back();
15202 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
15205 PromOpHandles.emplace_front(PromOp);
15210 if (isa<ConstantSDNode>(RepValue))
15219 default:
C = 0;
break;
15224 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
15232 PromOpHandles.emplace_front(PromOp);
15239 for (
unsigned i = 0; i < 2; ++i)
15240 if (isa<ConstantSDNode>(Ops[
C+i]))
15249 return N->getOperand(0);
15257 DAGCombinerInfo &DCI)
const {
15275 if (
N->getValueType(0) != MVT::i32 &&
15276 N->getValueType(0) != MVT::i64)
15279 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
15280 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
15283 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
15284 N->getOperand(0).getOpcode() !=
ISD::OR &&
15285 N->getOperand(0).getOpcode() !=
ISD::XOR &&
15296 while (!BinOps.
empty()) {
15304 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
15335 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15336 if (isa<ConstantSDNode>(Inputs[i]))
15347 SelectTruncOp[0].
insert(std::make_pair(
User,
15351 SelectTruncOp[0].
insert(std::make_pair(
User,
15354 SelectTruncOp[1].
insert(std::make_pair(
User,
15360 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
15369 SelectTruncOp[0].
insert(std::make_pair(
User,
15373 SelectTruncOp[0].
insert(std::make_pair(
User,
15376 SelectTruncOp[1].
insert(std::make_pair(
User,
15382 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
15383 bool ReallyNeedsExt =
false;
15387 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15388 if (isa<ConstantSDNode>(Inputs[i]))
15392 Inputs[i].getOperand(0).getValueSizeInBits();
15393 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
15398 OpBits-PromBits))) ||
15401 (OpBits-(PromBits-1)))) {
15402 ReallyNeedsExt =
true;
15410 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
15414 if (isa<ConstantSDNode>(Inputs[i]))
15417 SDValue InSrc = Inputs[i].getOperand(0);
15431 std::list<HandleSDNode> PromOpHandles;
15432 for (
auto &PromOp : PromOps)
15433 PromOpHandles.emplace_back(PromOp);
15439 while (!PromOpHandles.empty()) {
15441 PromOpHandles.pop_back();
15445 default:
C = 0;
break;
15450 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
15458 PromOpHandles.emplace_front(PromOp);
15468 (SelectTruncOp[1].count(PromOp.
getNode()) &&
15470 PromOpHandles.emplace_front(PromOp);
15478 for (
unsigned i = 0; i < 2; ++i) {
15479 if (!isa<ConstantSDNode>(Ops[
C+i]))
15496 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
15497 if (SI0 != SelectTruncOp[0].
end())
15499 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
15500 if (SI1 != SelectTruncOp[1].
end())
15509 if (!ReallyNeedsExt)
15510 return N->getOperand(0);
15517 N->getValueSizeInBits(0), PromBits),
15518 dl,
N->getValueType(0)));
15521 "Invalid extension type");
15524 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
15532 DAGCombinerInfo &DCI)
const {
15534 "Should be called with a SETCC node");
15536 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(2))->get();
15552 EVT VT =
N->getValueType(0);
15553 EVT OpVT =
LHS.getValueType();
15559 return DAGCombineTruncBoolExt(
N, DCI);
15564 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
15566 Op.getValueType() == MVT::f64;
15578combineElementTruncationToVectorTruncation(
SDNode *
N,
15579 DAGCombinerInfo &DCI)
const {
15581 "Should be called with a BUILD_VECTOR node");
15586 SDValue FirstInput =
N->getOperand(0);
15588 "The input operand must be an fp-to-int conversion.");
15597 bool IsSplat =
true;
15602 EVT TargetVT =
N->getValueType(0);
15603 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15604 SDValue NextOp =
N->getOperand(i);
15608 if (NextConversion != FirstConversion)
15616 if (
N->getOperand(i) != FirstInput)
15627 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15628 SDValue In =
N->getOperand(i).getOperand(0);
15651 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15653 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15666 "Should be called with a BUILD_VECTOR node");
15671 if (!
N->getValueType(0).getVectorElementType().isByteSized())
15674 bool InputsAreConsecutiveLoads =
true;
15675 bool InputsAreReverseConsecutive =
true;
15676 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
15677 SDValue FirstInput =
N->getOperand(0);
15678 bool IsRoundOfExtLoad =
false;
15683 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
15688 N->getNumOperands() == 1)
15691 if (!IsRoundOfExtLoad)
15692 FirstLoad = cast<LoadSDNode>(FirstInput);
15696 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
15698 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
15701 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
15707 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
15708 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
15709 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
15718 InputsAreConsecutiveLoads =
false;
15720 InputsAreReverseConsecutive =
false;
15723 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15728 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15729 "The loads cannot be both consecutive and reverse consecutive.");
15733 if (InputsAreConsecutiveLoads) {
15734 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
15738 ReturnSDVal = WideLoad;
15739 }
else if (InputsAreReverseConsecutive) {
15741 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
15746 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
15750 DAG.
getUNDEF(
N->getValueType(0)), Ops);
15754 for (
auto *LD : InputLoads)
15756 return ReturnSDVal;
15773 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15775 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
15777 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
15778 CorrectElems = CorrectElems >> 8;
15779 Elems = Elems >> 8;
15786 EVT VT =
N->getValueType(0);
15824 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
15844 if (Input && Input != Extract.
getOperand(0))
15850 Elems = Elems << 8;
15859 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15860 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15867 int TgtElemArrayIdx;
15869 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15870 if (InputSize + OutputSize == 40)
15871 TgtElemArrayIdx = 0;
15872 else if (InputSize + OutputSize == 72)
15873 TgtElemArrayIdx = 1;
15874 else if (InputSize + OutputSize == 48)
15875 TgtElemArrayIdx = 2;
15876 else if (InputSize + OutputSize == 80)
15877 TgtElemArrayIdx = 3;
15878 else if (InputSize + OutputSize == 96)
15879 TgtElemArrayIdx = 4;
15883 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15885 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15886 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15887 if (Elems != CorrectElems) {
15903 if (
N->getValueType(0) != MVT::v1i128)
15906 SDValue Operand =
N->getOperand(0);
15912 auto *LD = cast<LoadSDNode>(Operand);
15913 EVT MemoryType = LD->getMemoryVT();
15917 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15918 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15921 if (!ValidLDType ||
15927 LD->getChain(), LD->getBasePtr(),
15931 DAG.
getVTList(MVT::v1i128, MVT::Other),
15932 LoadOps, MemoryType, LD->getMemOperand());
15936 DAGCombinerInfo &DCI)
const {
15938 "Should be called with a BUILD_VECTOR node");
15943 if (!Subtarget.hasVSX())
15949 SDValue FirstInput =
N->getOperand(0);
15951 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15966 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15975 if (Subtarget.isISA3_1()) {
15981 if (
N->getValueType(0) != MVT::v2f64)
15992 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15996 SDValue Ext2 =
N->getOperand(1).getOperand(0);
16003 if (!Ext1Op || !Ext2Op)
16012 if (FirstElem == 0 && SecondElem == 1)
16014 else if (FirstElem == 2 && SecondElem == 3)
16022 return DAG.
getNode(NodeType, dl, MVT::v2f64,
16027 DAGCombinerInfo &DCI)
const {
16030 "Need an int -> FP conversion node here");
16041 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
16043 if (!
Op.getOperand(0).getValueType().isSimple())
16045 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
16046 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
16049 SDValue FirstOperand(
Op.getOperand(0));
16050 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
16051 (FirstOperand.getValueType() == MVT::i8 ||
16052 FirstOperand.getValueType() == MVT::i16);
16053 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
16055 bool DstDouble =
Op.getValueType() == MVT::f64;
16056 unsigned ConvOp =
Signed ?
16062 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
16071 SDValue ExtOps[] = { Ld, WidthConst };
16073 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
16075 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
16083 if (
Op.getOperand(0).getValueType() == MVT::i32)
16087 "UINT_TO_FP is supported only with FPCVT");
16091 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16096 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
16103 Subtarget.hasFPCVT()) ||
16105 SDValue Src =
Op.getOperand(0).getOperand(0);
16106 if (Src.getValueType() == MVT::f32) {
16108 DCI.AddToWorklist(Src.getNode());
16109 }
else if (Src.getValueType() != MVT::f64) {
16121 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
16124 DCI.AddToWorklist(
FP.getNode());
16148 switch (
N->getOpcode()) {
16153 Chain = LD->getChain();
16154 Base = LD->getBasePtr();
16155 MMO = LD->getMemOperand();
16174 MVT VecTy =
N->getValueType(0).getSimpleVT();
16182 Chain = Load.getValue(1);
16188 if (VecTy != MVT::v2f64) {
16215 switch (
N->getOpcode()) {
16220 Chain = ST->getChain();
16221 Base = ST->getBasePtr();
16222 MMO = ST->getMemOperand();
16242 SDValue Src =
N->getOperand(SrcOpnd);
16243 MVT VecTy = Src.getValueType().getSimpleVT();
16246 if (VecTy != MVT::v2f64) {
16252 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
16258 StoreOps, VecTy, MMO);
16265 DAGCombinerInfo &DCI)
const {
16268 unsigned Opcode =
N->getOperand(1).getOpcode();
16270 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
16274 &&
"Not a FP_TO_INT Instruction!");
16276 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
16277 EVT Op1VT =
N->getOperand(1).getValueType();
16280 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
16284 bool ValidTypeForStoreFltAsInt =
16285 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
16286 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
16289 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
16292 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
16293 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
16300 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
16306 cast<StoreSDNode>(
N)->getMemoryVT(),
16307 cast<StoreSDNode>(
N)->getMemOperand());
16315 bool PrevElemFromFirstVec = Mask[0] < NumElts;
16316 for (
int i = 1, e = Mask.size(); i < e; i++) {
16317 if (PrevElemFromFirstVec && Mask[i] < NumElts)
16319 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
16321 PrevElemFromFirstVec = !PrevElemFromFirstVec;
16333 FirstOp =
Op.getOperand(i);
16340 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
16350 Op =
Op.getOperand(0);
16366 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
16367 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
16369 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
16371 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
16372 for (
int I = 0, E = ShuffV.
size();
I < E; ++
I) {
16373 int Idx = ShuffV[
I];
16374 if (
Idx >= LHSFirstElt &&
Idx <= LHSLastElt)
16375 ShuffV[
I] += LHSEltFixup;
16376 else if (
Idx >= RHSFirstElt &&
Idx <= RHSLastElt)
16377 ShuffV[
I] += RHSEltFixup;
16388 SDLoc dl(OrigSToV);
16391 "Expecting a SCALAR_TO_VECTOR here");
16404 "Cannot produce a permuted scalar_to_vector for one element vector");
16406 unsigned ResultInElt = NumElts / 2;
16408 NewMask[ResultInElt] =
Idx->getZExtValue();
16417 int HalfVec,
int LHSLastElementDefined,
16418 int RHSLastElementDefined) {
16419 for (
int Index : ShuffV) {
16423 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
16424 (Index > LHSLastElementDefined))
16427 if ((RHSLastElementDefined >= 0) &&
16428 (Index > HalfVec + RHSLastElementDefined))
16435 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
16436 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
16452 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
16453 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
16456 if (SToVPermuted.
getValueType() != VecShuffOperandType)
16457 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
16458 return SToVPermuted;
16478 int NumElts =
LHS.getValueType().getVectorNumElements();
16488 if (!Subtarget.hasDirectMove())
16498 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
16507 if (SToVLHS || SToVRHS) {
16510 int ShuffleNumElts = ShuffV.
size();
16511 int HalfVec = ShuffleNumElts / 2;
16517 unsigned LHSNumValidElts = HalfVec;
16518 unsigned RHSNumValidElts = HalfVec;
16523 int LHSFirstElt = 0;
16524 int RHSFirstElt = ShuffleNumElts;
16525 int LHSLastElt = -1;
16526 int RHSLastElt = -1;
16534 int LHSScalarSize = 0;
16535 int RHSScalarSize = 0;
16538 if (!IsLittleEndian && LHSScalarSize >= 64)
16543 if (!IsLittleEndian && RHSScalarSize >= 64)
16546 if (LHSScalarSize != 0)
16548 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
16549 LHSLastElt, LHS, SToVLHS, DAG, Subtarget);
16550 if (RHSScalarSize != 0)
16552 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
16553 RHSLastElt, RHS, SToVRHS, DAG, Subtarget);
16564 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
16565 LHSNumValidElts, RHSNumValidElts, Subtarget);
16570 if (!isa<ShuffleVectorSDNode>(Res))
16572 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
16591 if (IsLittleEndian) {
16594 if (Mask[0] < NumElts)
16595 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
16599 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16604 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
16608 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
16613 if (Mask[0] < NumElts)
16614 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
16618 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
16623 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
16627 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
16634 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
16637 if (IsLittleEndian)
16646 DAGCombinerInfo &DCI)
const {
16648 "Not a reverse memop pattern!");
16653 auto I =
Mask.rbegin();
16654 auto E =
Mask.rend();
16656 for (;
I != E; ++
I) {
16673 if (!Subtarget.hasP9Vector())
16676 if(!IsElementReverse(SVN))
16684 if (
Use.getResNo() == 0 &&
16715 if (IntrinsicID == Intrinsic::ppc_stdcx)
16717 else if (IntrinsicID == Intrinsic::ppc_stwcx)
16719 else if (IntrinsicID == Intrinsic::ppc_sthcx)
16721 else if (IntrinsicID == Intrinsic::ppc_stbcx)
16747 switch (
N->getOpcode()) {
16750 return combineADD(
N, DCI);
16759 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
16769 if (!isUInt<32>(Imm))
16776 return combineSHL(
N, DCI);
16778 return combineSRA(
N, DCI);
16780 return combineSRL(
N, DCI);
16782 return combineMUL(
N, DCI);
16785 return combineFMALike(
N, DCI);
16788 return N->getOperand(0);
16792 return N->getOperand(0);
16798 return N->getOperand(0);
16804 return DAGCombineExtBoolTrunc(
N, DCI);
16806 return combineTRUNCATE(
N, DCI);
16808 if (
SDValue CSCC = combineSetCC(
N, DCI))
16812 return DAGCombineTruncBoolExt(
N, DCI);
16815 return combineFPToIntToFP(
N, DCI);
16818 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
16819 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
16821 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
16824 EVT Op1VT =
N->getOperand(1).getValueType();
16825 unsigned Opcode =
N->getOperand(1).getOpcode();
16829 SDValue Val = combineStoreFPToInt(
N, DCI);
16836 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
16842 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
16843 N->getOperand(1).getNode()->hasOneUse() &&
16844 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
16845 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
16849 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
16853 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
16860 if (Op1VT.
bitsGT(mVT)) {
16865 if (Op1VT == MVT::i64)
16870 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
16874 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
16875 cast<StoreSDNode>(
N)->getMemOperand());
16881 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
16883 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
16888 auto *ST = cast<StoreSDNode>(
N);
16890 ST->getBasePtr(), ST->getOffset(), MemVT,
16891 ST->getMemOperand(), ST->getAddressingMode(),
16895 return ST->isUnindexed()
16905 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
16906 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
16913 EVT VT = LD->getValueType(0);
16920 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16921 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16932 auto ReplaceTwoFloatLoad = [&]() {
16933 if (VT != MVT::i64)
16948 if (!LD->hasNUsesOfValue(2, 0))
16951 auto UI = LD->user_begin();
16952 while (UI.getUse().getResNo() != 0) ++UI;
16954 while (UI.getUse().getResNo() != 0) ++UI;
16955 SDNode *RightShift = *UI;
16963 if (RightShift->getOpcode() !=
ISD::SRL ||
16964 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
16965 RightShift->getConstantOperandVal(1) != 32 ||
16966 !RightShift->hasOneUse())
16969 SDNode *Trunc2 = *RightShift->user_begin();
16979 Bitcast->getValueType(0) != MVT::f32)
16991 SDValue BasePtr = LD->getBasePtr();
16992 if (LD->isIndexed()) {
16994 "Non-pre-inc AM on PPC?");
17002 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
17003 LD->getPointerInfo(), LD->getAlign(),
17004 MMOFlags, LD->getAAInfo());
17010 LD->getPointerInfo().getWithOffset(4),
17013 if (LD->isIndexed()) {
17027 if (ReplaceTwoFloatLoad())
17030 EVT MemVT = LD->getMemoryVT();
17033 if (LD->isUnindexed() && VT.
isVector() &&
17036 !Subtarget.hasP8Vector() &&
17037 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
17038 VT == MVT::v4f32))) &&
17039 LD->getAlign() < ABIAlignment) {
17041 SDValue Chain = LD->getChain();
17070 MVT PermCntlTy, PermTy, LDTy;
17071 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
17072 : Intrinsic::ppc_altivec_lvsl;
17073 IntrLD = Intrinsic::ppc_altivec_lvx;
17074 IntrPerm = Intrinsic::ppc_altivec_vperm;
17075 PermCntlTy = MVT::v16i8;
17076 PermTy = MVT::v4i32;
17095 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
17099 BaseLoadOps, LDTy, BaseMMO);
17108 int IncValue = IncOffset;
17125 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
17129 ExtraLoadOps, LDTy, ExtraMMO);
17140 if (isLittleEndian)
17142 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
17145 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
17148 Perm = Subtarget.hasAltivec()
17164 unsigned IID =
N->getConstantOperandVal(0);
17166 : Intrinsic::ppc_altivec_lvsl);
17167 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
17174 .
zext(
Add.getScalarValueSizeInBits()))) {
17175 SDNode *BasePtr =
Add->getOperand(0).getNode();
17176 for (
SDNode *U : BasePtr->users()) {
17178 U->getConstantOperandVal(0) == IID) {
17188 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
17189 SDNode *BasePtr =
Add->getOperand(0).getNode();
17190 for (
SDNode *U : BasePtr->users()) {
17192 isa<ConstantSDNode>(U->getOperand(1)) &&
17193 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
17199 V->getConstantOperandVal(0) == IID) {
17211 (IID == Intrinsic::ppc_altivec_vmaxsw ||
17212 IID == Intrinsic::ppc_altivec_vmaxsh ||
17213 IID == Intrinsic::ppc_altivec_vmaxsb)) {
17244 switch (
N->getConstantOperandVal(1)) {
17247 case Intrinsic::ppc_altivec_vsum4sbs:
17248 case Intrinsic::ppc_altivec_vsum4shs:
17249 case Intrinsic::ppc_altivec_vsum4ubs: {
17255 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
17256 APInt APSplatBits, APSplatUndef;
17257 unsigned SplatBitSize;
17260 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
17263 if (BVNIsConstantSplat && APSplatBits == 0)
17268 case Intrinsic::ppc_vsx_lxvw4x:
17269 case Intrinsic::ppc_vsx_lxvd2x:
17281 switch (
N->getConstantOperandVal(1)) {
17284 case Intrinsic::ppc_vsx_stxvw4x:
17285 case Intrinsic::ppc_vsx_stxvd2x:
17294 bool Is64BitBswapOn64BitTgt =
17295 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
17297 N->getOperand(0).hasOneUse();
17298 if (IsSingleUseNormalLd &&
17299 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
17300 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
17311 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
17312 MVT::i64 : MVT::i32, MVT::Other),
17313 Ops, LD->getMemoryVT(), LD->getMemOperand());
17317 if (
N->getValueType(0) == MVT::i16)
17334 !IsSingleUseNormalLd)
17336 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
17339 if (!LD->isSimple())
17341 SDValue BasePtr = LD->getBasePtr();
17343 LD->getPointerInfo(), LD->getAlign());
17348 LD->getMemOperand(), 4, 4);
17358 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
17367 if (!
N->getOperand(0).hasOneUse() &&
17368 !
N->getOperand(1).hasOneUse() &&
17369 !
N->getOperand(2).hasOneUse()) {
17372 SDNode *VCMPrecNode =
nullptr;
17374 SDNode *LHSN =
N->getOperand(0).getNode();
17380 VCMPrecNode =
User;
17392 SDNode *FlagUser =
nullptr;
17394 FlagUser ==
nullptr; ++UI) {
17395 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
17408 return SDValue(VCMPrecNode, 0);
17418 ISD::CondCode CC = cast<CondCodeSDNode>(
N->getOperand(1))->get();
17430 auto RHSAPInt =
RHS->getAsAPIntVal();
17431 if (!RHSAPInt.isIntN(64))
17434 unsigned Val = RHSAPInt.getZExtValue();
17435 auto isImpossibleCompare = [&]() {
17438 if (Val != 0 && Val != 1) {
17440 return N->getOperand(0);
17443 N->getOperand(0),
N->getOperand(4));
17448 unsigned StoreWidth = 0;
17451 if (
SDValue Impossible = isImpossibleCompare())
17465 auto *MemNode = cast<MemSDNode>(
LHS);
17468 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
17469 MemNode->getMemoryVT(), MemNode->getMemOperand());
17473 if (
N->getOperand(0) ==
LHS.getValue(1))
17474 InChain =
LHS.getOperand(0);
17486 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
17492 assert(isDot &&
"Can't compare against a vector result!");
17494 if (
SDValue Impossible = isImpossibleCompare())
17497 bool BranchOnWhenPredTrue = (CC ==
ISD::SETEQ) ^ (Val == 0);
17504 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
17509 switch (
LHS.getConstantOperandVal(1)) {
17528 N->getOperand(4), CompNode.
getValue(1));
17533 return DAGCombineBuildVector(
N, DCI);
17546 EVT VT =
N->getValueType(0);
17547 if (VT == MVT::i64 && !Subtarget.
isPPC64())
17549 if ((VT != MVT::i32 && VT != MVT::i64) ||
17557 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
17577 const APInt &DemandedElts,
17579 unsigned Depth)
const {
17581 switch (
Op.getOpcode()) {
17585 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
17586 Known.
Zero = 0xFFFF0000;
17590 if (
Op.getResNo() == 0) {
17595 Known.
Zero = ~1ULL;
17600 switch (
Op.getConstantOperandVal(0)) {
17602 case Intrinsic::ppc_altivec_vcmpbfp_p:
17603 case Intrinsic::ppc_altivec_vcmpeqfp_p:
17604 case Intrinsic::ppc_altivec_vcmpequb_p:
17605 case Intrinsic::ppc_altivec_vcmpequh_p:
17606 case Intrinsic::ppc_altivec_vcmpequw_p:
17607 case Intrinsic::ppc_altivec_vcmpequd_p:
17608 case Intrinsic::ppc_altivec_vcmpequq_p:
17609 case Intrinsic::ppc_altivec_vcmpgefp_p:
17610 case Intrinsic::ppc_altivec_vcmpgtfp_p:
17611 case Intrinsic::ppc_altivec_vcmpgtsb_p:
17612 case Intrinsic::ppc_altivec_vcmpgtsh_p:
17613 case Intrinsic::ppc_altivec_vcmpgtsw_p:
17614 case Intrinsic::ppc_altivec_vcmpgtsd_p:
17615 case Intrinsic::ppc_altivec_vcmpgtsq_p:
17616 case Intrinsic::ppc_altivec_vcmpgtub_p:
17617 case Intrinsic::ppc_altivec_vcmpgtuh_p:
17618 case Intrinsic::ppc_altivec_vcmpgtuw_p:
17619 case Intrinsic::ppc_altivec_vcmpgtud_p:
17620 case Intrinsic::ppc_altivec_vcmpgtuq_p:
17627 switch (
Op.getConstantOperandVal(1)) {
17630 case Intrinsic::ppc_load2r:
17632 Known.
Zero = 0xFFFF0000;
17663 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
17672 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
17674 LoopSize +=
TII->getInstSizeInBytes(J);
17679 if (LoopSize > 16 && LoopSize <= 32)
17693 if (Constraint.
size() == 1) {
17694 switch (Constraint[0]) {
17712 }
else if (Constraint ==
"wc") {
17714 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
17715 Constraint ==
"wf" || Constraint ==
"ws" ||
17716 Constraint ==
"wi" || Constraint ==
"ww") {
17729 Value *CallOperandVal =
info.CallOperandVal;
17732 if (!CallOperandVal)
17739 else if ((
StringRef(constraint) ==
"wa" ||
17751 switch (*constraint) {
17781std::pair<unsigned, const TargetRegisterClass *>
17785 if (Constraint.
size() == 1) {
17787 switch (Constraint[0]) {
17789 if (VT == MVT::i64 && Subtarget.
isPPC64())
17790 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
17791 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
17793 if (VT == MVT::i64 && Subtarget.
isPPC64())
17794 return std::make_pair(0U, &PPC::G8RCRegClass);
17795 return std::make_pair(0U, &PPC::GPRCRegClass);
17801 if (Subtarget.hasSPE()) {
17802 if (VT == MVT::f32 || VT == MVT::i32)
17803 return std::make_pair(0U, &PPC::GPRCRegClass);
17804 if (VT == MVT::f64 || VT == MVT::i64)
17805 return std::make_pair(0U, &PPC::SPERCRegClass);
17807 if (VT == MVT::f32 || VT == MVT::i32)
17808 return std::make_pair(0U, &PPC::F4RCRegClass);
17809 if (VT == MVT::f64 || VT == MVT::i64)
17810 return std::make_pair(0U, &PPC::F8RCRegClass);
17814 if (Subtarget.hasAltivec() && VT.
isVector())
17815 return std::make_pair(0U, &PPC::VRRCRegClass);
17816 else if (Subtarget.hasVSX())
17818 return std::make_pair(0U, &PPC::VFRCRegClass);
17821 return std::make_pair(0U, &PPC::CRRCRegClass);
17823 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
17825 return std::make_pair(0U, &PPC::CRBITRCRegClass);
17826 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
17827 Constraint ==
"wf" || Constraint ==
"wi") &&
17828 Subtarget.hasVSX()) {
17832 return std::make_pair(0U, &PPC::VSRCRegClass);
17833 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17834 return std::make_pair(0U, &PPC::VSSRCRegClass);
17835 return std::make_pair(0U, &PPC::VSFRCRegClass);
17836 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
17837 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17838 return std::make_pair(0U, &PPC::VSSRCRegClass);
17840 return std::make_pair(0U, &PPC::VSFRCRegClass);
17841 }
else if (Constraint ==
"lr") {
17842 if (VT == MVT::i64)
17843 return std::make_pair(0U, &PPC::LR8RCRegClass);
17845 return std::make_pair(0U, &PPC::LRRCRegClass);
17850 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
17854 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
17855 int VSNum = atoi(Constraint.
data() + 3);
17856 assert(VSNum >= 0 && VSNum <= 63 &&
17857 "Attempted to access a vsr out of range");
17859 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
17860 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
17865 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
17866 int RegNum = atoi(Constraint.
data() + 2);
17867 if (RegNum > 31 || RegNum < 0)
17869 if (VT == MVT::f32 || VT == MVT::i32)
17870 return Subtarget.hasSPE()
17871 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
17872 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
17873 if (VT == MVT::f64 || VT == MVT::i64)
17874 return Subtarget.hasSPE()
17875 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
17876 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
17880 std::pair<unsigned, const TargetRegisterClass *> R =
17889 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
17890 PPC::GPRCRegClass.contains(R.first))
17891 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
17892 PPC::sub_32, &PPC::G8RCRegClass),
17893 &PPC::G8RCRegClass);
17896 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
17897 R.first = PPC::CR0;
17898 R.second = &PPC::CRRCRegClass;
17902 if (Subtarget.
isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
17903 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
17904 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
17905 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
17906 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
17907 "default AIX AltiVec ABI and cannot be used\n";
17917 std::vector<SDValue> &Ops,
17922 if (Constraint.
size() > 1)
17925 char Letter = Constraint[0];
17940 EVT TCVT = MVT::i64;
17945 if (isInt<16>(
Value))
17949 if (isShiftedUInt<16, 16>(
Value))
17953 if (isShiftedInt<16, 16>(
Value))
17957 if (isUInt<16>(
Value))
17973 if (isInt<16>(-
Value))
17981 if (Result.getNode()) {
17982 Ops.push_back(Result);
17993 if (
I.getNumOperands() <= 1)
17995 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17997 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17998 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17999 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
18002 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
18030 switch (AM.
Scale) {
18058 unsigned Depth =
Op.getConstantOperandVal(0);
18082 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
18090 unsigned Depth =
Op.getConstantOperandVal(0);
18097 bool isPPC64 = PtrVT == MVT::i64;
18103 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
18105 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
18115#define GET_REGISTER_MATCHER
18116#include "PPCGenAsmMatcher.inc"
18120 bool IsPPC64 = Subtarget.
isPPC64();
18132 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
18138 Reg = Reg.id() - PPC::R0 + PPC::X0;
18160 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
18178 unsigned Intrinsic)
const {
18179 switch (Intrinsic) {
18180 case Intrinsic::ppc_atomicrmw_xchg_i128:
18181 case Intrinsic::ppc_atomicrmw_add_i128:
18182 case Intrinsic::ppc_atomicrmw_sub_i128:
18183 case Intrinsic::ppc_atomicrmw_nand_i128:
18184 case Intrinsic::ppc_atomicrmw_and_i128:
18185 case Intrinsic::ppc_atomicrmw_or_i128:
18186 case Intrinsic::ppc_atomicrmw_xor_i128:
18187 case Intrinsic::ppc_cmpxchg_i128:
18189 Info.memVT = MVT::i128;
18190 Info.ptrVal =
I.getArgOperand(0);
18196 case Intrinsic::ppc_atomic_load_i128:
18198 Info.memVT = MVT::i128;
18199 Info.ptrVal =
I.getArgOperand(0);
18204 case Intrinsic::ppc_atomic_store_i128:
18206 Info.memVT = MVT::i128;
18207 Info.ptrVal =
I.getArgOperand(2);
18212 case Intrinsic::ppc_altivec_lvx:
18213 case Intrinsic::ppc_altivec_lvxl:
18214 case Intrinsic::ppc_altivec_lvebx:
18215 case Intrinsic::ppc_altivec_lvehx:
18216 case Intrinsic::ppc_altivec_lvewx:
18217 case Intrinsic::ppc_vsx_lxvd2x:
18218 case Intrinsic::ppc_vsx_lxvw4x:
18219 case Intrinsic::ppc_vsx_lxvd2x_be:
18220 case Intrinsic::ppc_vsx_lxvw4x_be:
18221 case Intrinsic::ppc_vsx_lxvl:
18222 case Intrinsic::ppc_vsx_lxvll: {
18224 switch (Intrinsic) {
18225 case Intrinsic::ppc_altivec_lvebx:
18228 case Intrinsic::ppc_altivec_lvehx:
18231 case Intrinsic::ppc_altivec_lvewx:
18234 case Intrinsic::ppc_vsx_lxvd2x:
18235 case Intrinsic::ppc_vsx_lxvd2x_be:
18245 Info.ptrVal =
I.getArgOperand(0);
18252 case Intrinsic::ppc_altivec_stvx:
18253 case Intrinsic::ppc_altivec_stvxl:
18254 case Intrinsic::ppc_altivec_stvebx:
18255 case Intrinsic::ppc_altivec_stvehx:
18256 case Intrinsic::ppc_altivec_stvewx:
18257 case Intrinsic::ppc_vsx_stxvd2x:
18258 case Intrinsic::ppc_vsx_stxvw4x:
18259 case Intrinsic::ppc_vsx_stxvd2x_be:
18260 case Intrinsic::ppc_vsx_stxvw4x_be:
18261 case Intrinsic::ppc_vsx_stxvl:
18262 case Intrinsic::ppc_vsx_stxvll: {
18264 switch (Intrinsic) {
18265 case Intrinsic::ppc_altivec_stvebx:
18268 case Intrinsic::ppc_altivec_stvehx:
18271 case Intrinsic::ppc_altivec_stvewx:
18274 case Intrinsic::ppc_vsx_stxvd2x:
18275 case Intrinsic::ppc_vsx_stxvd2x_be:
18285 Info.ptrVal =
I.getArgOperand(1);
18292 case Intrinsic::ppc_stdcx:
18293 case Intrinsic::ppc_stwcx:
18294 case Intrinsic::ppc_sthcx:
18295 case Intrinsic::ppc_stbcx: {
18297 auto Alignment =
Align(8);
18298 switch (Intrinsic) {
18299 case Intrinsic::ppc_stdcx:
18302 case Intrinsic::ppc_stwcx:
18304 Alignment =
Align(4);
18306 case Intrinsic::ppc_sthcx:
18308 Alignment =
Align(2);
18310 case Intrinsic::ppc_stbcx:
18312 Alignment =
Align(1);
18317 Info.ptrVal =
I.getArgOperand(0);
18319 Info.align = Alignment;
18338 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
18339 if (
Op.isMemset() && Subtarget.hasVSX()) {
18344 if (TailSize > 2 && TailSize <= 4) {
18349 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
18368 return !(BitSize == 0 || BitSize > 64);
18376 return NumBits1 == 64 && NumBits2 == 32;
18384 return NumBits1 == 64 && NumBits2 == 32;
18390 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
18391 EVT MemVT = LD->getMemoryVT();
18392 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
18393 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
18409 "invalid fpext types");
18411 if (DestVT == MVT::f128)
18417 return isInt<16>(Imm) || isUInt<16>(Imm);
18421 return isInt<16>(Imm) || isUInt<16>(Imm);
18426 unsigned *
Fast)
const {
18440 !Subtarget.allowsUnalignedFPAccess())
18444 if (Subtarget.hasVSX()) {
18445 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
18446 VT != MVT::v4f32 && VT != MVT::v4i32)
18453 if (VT == MVT::ppcf128)
18467 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
18468 if (!ConstNode->getAPIntValue().isSignedIntN(64))
18476 int64_t Imm = ConstNode->getSExtValue();
18477 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
18479 if (isInt<16>(Imm))
18504 return Subtarget.hasP9Vector();
18512 if (!
I->hasOneUse())
18516 assert(
User &&
"A single use instruction with no uses.");
18518 switch (
I->getOpcode()) {
18519 case Instruction::FMul: {
18521 if (
User->getOpcode() != Instruction::FSub &&
18522 User->getOpcode() != Instruction::FAdd)
18535 case Instruction::Load: {
18548 if (
User->getOpcode() != Instruction::Store)
18568 static const MCPhysReg ScratchRegs[] = {
18569 PPC::X12, PPC::LR8, PPC::CTR8, 0
18572 return ScratchRegs;
18576 const Constant *PersonalityFn)
const {
18577 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
18581 const Constant *PersonalityFn)
const {
18582 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
18587 EVT VT ,
unsigned DefinedValues)
const {
18588 if (VT == MVT::v2i64)
18589 return Subtarget.hasDirectMove();
18591 if (Subtarget.hasVSX())
18625 bool LegalOps,
bool OptForSize,
18627 unsigned Depth)
const {
18631 unsigned Opc =
Op.getOpcode();
18632 EVT VT =
Op.getValueType();
18657 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
18661 N0Cost,
Depth + 1);
18665 N1Cost,
Depth + 1);
18667 if (NegN0 && N0Cost <= N1Cost) {
18668 Cost = std::min(N0Cost, N2Cost);
18669 return DAG.
getNode(
Opc, Loc, VT, NegN0, N1, NegN2, Flags);
18670 }
else if (NegN1) {
18671 Cost = std::min(N1Cost, N2Cost);
18672 return DAG.
getNode(
Opc, Loc, VT, N0, NegN1, NegN2, Flags);
18691 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.
isTargetLinux())
18697 bool ForCodeSize)
const {
18698 if (!VT.
isSimple() || !Subtarget.hasVSX())
18708 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
18713 APSInt IntResult(16,
false);
18718 if (IsExact && IntResult <= 15 && IntResult >= -16)
18720 return Imm.isZero();
18723 return Imm.isPosZero();
18735 unsigned Opcode =
N->getOpcode();
18736 unsigned TargetOpcode;
18755 if (Mask->getZExtValue() == OpSizeInBits - 1)
18762 DAGCombinerInfo &DCI)
const {
18763 EVT VT =
N->getValueType(0);
18766 unsigned Opc =
N->getOpcode();
18768 "Unexpected opcode.");
18775 if (EltTy != MVT::i64 && EltTy != MVT::i32)
18780 bool AddSplatCase =
false;
18784 AddSplatCase =
true;
18788 if (!AddSplatCase) {
18792 unsigned SplatBitSize;
18794 APInt APSplatBits, APSplatUndef;
18796 bool BVNIsConstantSplat =
18799 if (!BVNIsConstantSplat || SplatBitSize != EltBits)
18810 if (SplatBits == (EltBits - 1)) {
18824 return DCI.DAG.getNode(NewOpc,
DL, VT, N0, SplatOnes);
18832 if (EltTy != MVT::i64 || SplatBits != 1)
18838SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18842 if (
N->getValueType(0).isVector())
18843 return combineVectorShift(
N, DCI);
18847 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
18850 N->getValueType(0) != MVT::i64)
18865 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
18871SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18875 if (
N->getValueType(0).isVector())
18876 return combineVectorShift(
N, DCI);
18881SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18885 if (
N->getValueType(0).isVector())
18886 return combineVectorShift(
N, DCI);
18903 auto isZextOfCompareWithConstant = [](
SDValue Op) {
18905 Op.getValueType() != MVT::i64)
18909 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
18910 Cmp.getOperand(0).getValueType() != MVT::i64)
18913 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
18914 int64_t NegConstant = 0 -
Constant->getSExtValue();
18917 return isInt<16>(NegConstant);
18923 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
18924 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
18927 if (LHSHasPattern && !RHSHasPattern)
18929 else if (!LHSHasPattern && !RHSHasPattern)
18933 EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18936 SDValue Z = Cmp.getOperand(0);
18937 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
18938 int64_t NegConstant = 0 -
Constant->getSExtValue();
18940 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
18951 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18969 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
19010 if (!GSDN || !ConstNode)
19017 if (!isInt<34>(NewOffset))
19030SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19050 DAGCombinerInfo &DCI)
const {
19052 if (Subtarget.useCRBits()) {
19054 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
19055 return CRTruncValue;
19062 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
19065 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
19075 EltToExtract = EltToExtract ? 0 : 1;
19085 return DCI.DAG.getNode(
19087 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
19092SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
19096 if (!ConstOpOrElement)
19104 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
19128 return IsAddOne && IsNeg ? VT.
isVector() :
true;
19132 EVT VT =
N->getValueType(0);
19139 if ((MulAmtAbs - 1).isPowerOf2()) {
19143 if (!IsProfitable(IsNeg,
true, VT))
19156 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
19160 if (!IsProfitable(IsNeg,
false, VT))
19181 DAGCombinerInfo &DCI)
const {
19186 EVT VT =
N->getValueType(0);
19189 unsigned Opc =
N->getOpcode();
19191 bool LegalOps = !DCI.isBeforeLegalizeOps();
19199 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
19215bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
19232 if (!Callee ||
Callee->isVarArg())
19245bool PPCTargetLowering::
19246isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
19249 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
19251 if (CI->getBitWidth() > 64)
19253 int64_t ConstVal = CI->getZExtValue();
19254 return isUInt<16>(ConstVal) ||
19255 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
19264PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
19270 if ((Flags & FlagSet) == FlagSet)
19273 if ((Flags & FlagSet) == FlagSet)
19276 if ((Flags & FlagSet) == FlagSet)
19279 if ((Flags & FlagSet) == FlagSet)
19300 if ((FrameIndexAlign % 4) != 0)
19301 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
19302 if ((FrameIndexAlign % 16) != 0)
19303 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
19307 if ((FrameIndexAlign % 4) == 0)
19309 if ((FrameIndexAlign % 16) == 0)
19322 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
19323 if ((Imm & 0x3) == 0)
19325 if ((Imm & 0xf) == 0)
19331 const APInt &ConstImm = CN->getAPIntValue();
19350 const APInt &ConstImm = CN->getAPIntValue();
19360 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
19372 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
19373 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
19374 isValidPCRelNode<JumpTableSDNode>(
N) ||
19375 isValidPCRelNode<BlockAddressSDNode>(
N));
19380unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
19385 if (!Subtarget.hasP9Vector())
19390 if (Subtarget.hasPrefixInstrs())
19393 if (Subtarget.hasSPE())
19402 unsigned ParentOp = Parent->
getOpcode();
19406 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
19407 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
19418 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
19419 if (LSB->isIndexed())
19424 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
19425 assert(MN &&
"Parent should be a MemSDNode!");
19430 "Not expecting scalar integers larger than 16 bytes!");
19433 else if (
Size == 32)
19440 else if (
Size == 256) {
19441 assert(Subtarget.pairedVectorMemops() &&
19442 "256-bit vectors are only available when paired vector memops is "
19450 else if (MemVT == MVT::f128 || MemVT.
isVector())
19460 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
19481 FlagSet &= ~PPC::MOF_NoExt;
19486 bool IsNonP1034BitConst =
19490 IsNonP1034BitConst)
19503 int16_t ForceXFormImm = 0;
19506 Disp =
N.getOperand(0);
19507 Base =
N.getOperand(1);
19518 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
19519 Disp =
N.getOperand(0);
19520 Base =
N.getOperand(1);
19534 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID> CC)
const {
19540 if (PartVT == MVT::f64 &&
19541 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
19550SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
19554 EVT RetVT =
Op.getValueType();
19561 EVT ArgVT =
N.getValueType();
19565 Entry.IsZExt = !Entry.IsSExt;
19566 Args.push_back(Entry);
19574 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
19580 .setTailCall(isTailCall)
19587SDValue PPCTargetLowering::lowerLibCallBasedOnType(
19588 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
19590 if (
Op.getValueType() == MVT::f32)
19591 return lowerToLibCall(LibCallFloatName,
Op, DAG);
19593 if (
Op.getValueType() == MVT::f64)
19594 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
19599bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
19601 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
19605bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
19606 return Op.getNode()->getFlags().hasApproximateFuncs();
19609bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
19613SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
19614 const char *LibCallFloatName,
19615 const char *LibCallDoubleNameFinite,
19616 const char *LibCallFloatNameFinite,
19619 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
19622 if (!isLowringToMASSFiniteSafe(
Op))
19623 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
19626 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
19627 LibCallDoubleNameFinite,
Op, DAG);
19631 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
19632 "__xl_powf_finite",
Op, DAG);
19636 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
19637 "__xl_sinf_finite",
Op, DAG);
19641 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
19642 "__xl_cosf_finite",
Op, DAG);
19646 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
19647 "__xl_logf_finite",
Op, DAG);
19651 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
19652 "__xl_log10f_finite",
Op, DAG);
19656 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
19657 "__xl_expf_finite",
Op, DAG);
19664 if (!isa<FrameIndexSDNode>(
N))
19682 unsigned Flags = computeMOFlags(Parent,
N, DAG);
19694 "Must be using PC-Relative calls when a valid PC-Relative node is "
19724 Disp =
N.getOperand(1).getOperand(0);
19729 Base =
N.getOperand(0);
19736 auto *CN = cast<ConstantSDNode>(
N);
19737 EVT CNType = CN->getValueType(0);
19738 uint64_t CNImm = CN->getZExtValue();
19749 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
19751 int32_t
Addr = (int32_t)CNImm;
19756 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
19772 unsigned Opcode =
N.getOpcode();
19780 Base =
N.getOperand(0);
19799 Base = FI ?
N :
N.getOperand(1);
19811 bool IsVarArg)
const {
19821 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
19857 return Intrinsic::ppc_atomicrmw_xchg_i128;
19859 return Intrinsic::ppc_atomicrmw_add_i128;
19861 return Intrinsic::ppc_atomicrmw_sub_i128;
19863 return Intrinsic::ppc_atomicrmw_and_i128;
19865 return Intrinsic::ppc_atomicrmw_or_i128;
19867 return Intrinsic::ppc_atomicrmw_xor_i128;
19869 return Intrinsic::ppc_atomicrmw_nand_i128;
19886 {AlignedAddr, IncrLo, IncrHi});
19892 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19913 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
19920 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19924 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.
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
Module.h This file contains the declarations for the Module class.
This defines the Use class.
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).
Register const TargetRegisterInfo * TRI
static bool isConstantOrUndef(const SDValue Op)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static SDValue DAGCombineAddc(SDNode *N, llvm::PPCTargetLowering::DAGCombinerInfo &DCI)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static bool isShuffleMaskInRange(const SmallVectorImpl< int > &ShuffV, int HalfVec, int LHSLastElementDefined, int RHSLastElementDefined)
static SDValue addShuffleForVecExtend(SDNode *N, SelectionDAG &DAG, SDValue Input, uint64_t Elems, uint64_t CorrectElems)
static cl::opt< bool > DisablePPCUnaligned("disable-ppc-unaligned", cl::desc("disable unaligned load/store generation on PPC"), cl::Hidden)
static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool findConsecutiveLoad(LoadSDNode *LD, SelectionDAG &DAG)
static SDValue generateEquivalentSub(SDNode *N, int Size, bool Complement, bool Swap, SDLoc &DL, SelectionDAG &DAG)
This function is called when we have proved that a SETCC node can be replaced by subtraction (and oth...
static unsigned mapArgRegToOffsetAIX(unsigned Reg, const PPCFrameLowering *FL)
static void CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool IsPPC64, SDValue Arg, int SPDiff, unsigned ArgOffset, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
CalculateTailCallArgDest - Remember Argument for later processing.
static SDValue combineADDToMAT_PCREL_ADDR(SDNode *N, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setAlignFlagsForFI(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Set alignment flags based on whether or not the Frame Index is aligned.
static bool isTOCSaveRestoreRequired(const PPCSubtarget &Subtarget)
static void updateForAIXShLibTLSModelOpt(TLSModel::Model &Model, SelectionDAG &DAG, const TargetMachine &TM)
updateForAIXShLibTLSModelOpt - Helper to initialize TLS model opt settings, and then apply the update...
static bool provablyDisjointOr(SelectionDAG &DAG, const SDValue &N)
Used when computing address flags for selecting loads and stores.
static bool callsShareTOCBase(const Function *Caller, const GlobalValue *CalleeGV, const TargetMachine &TM)
static SDValue generateSToVPermutedForVecShuffle(int ScalarSize, uint64_t ShuffleEltWidth, unsigned &NumValidElts, int FirstElt, int &LastElt, SDValue VecShuffOperand, SDValue SToVNode, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
constexpr uint64_t AIXSmallTlsPolicySizeLimit
static bool isPCRelNode(SDValue N)
static void LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, SDValue Arg, SDValue PtrOff, int SPDiff, unsigned ArgOffset, bool isPPC64, bool isTailCall, bool isVector, SmallVectorImpl< SDValue > &MemOpChains, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments, const SDLoc &dl)
LowerMemOpCallTo - Store the argument to the stack or remember it in case of tail calls.
static cl::opt< unsigned > PPCGatherAllAliasesMaxDepth("ppc-gather-alias-max-depth", cl::init(18), cl::Hidden, cl::desc("max depth when checking alias info in GatherAllAliases()"))
static bool areCallingConvEligibleForTCO_64SVR4(CallingConv::ID CallerCC, CallingConv::ID CalleeCC)
static const MCPhysReg FPR[]
FPR - The set of FP registers that should be allocated for arguments on Darwin and AIX.
static SDNode * isBLACompatibleAddress(SDValue Op, SelectionDAG &DAG)
isCallCompatibleAddress - Return the immediate to use if the specified 32-bit value is representable ...
static Align CalculateStackSlotAlignment(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotAlignment - Calculates the alignment of this argument on the stack.
static bool IsSelect(MachineInstr &MI)
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag, EVT CarryType, SelectionDAG &DAG, const PPCSubtarget &STI)
static bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static void fixupShuffleMaskForPermutedSToV(SmallVectorImpl< int > &ShuffV, int LHSFirstElt, int LHSLastElt, int RHSFirstElt, int RHSLastElt, int HalfVec, unsigned LHSNumValidElts, unsigned RHSNumValidElts, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableSCO("disable-ppc-sco", cl::desc("disable sibling call optimization on ppc"), cl::Hidden)
static void fixupFuncForFI(SelectionDAG &DAG, int FrameIdx, EVT VT)
static cl::opt< bool > DisablePPCPreinc("disable-ppc-preinc", cl::desc("disable preincrement load/store generation on PPC"), cl::Hidden)
static Intrinsic::ID getIntrinsicForAtomicRMWBinOp128(AtomicRMWInst::BinOp BinOp)
static SDValue convertFPToInt(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize)
CalculateStackSlotSize - Calculates the size reserved for this argument on the stack.
static int CalculateTailCallSPDiff(SelectionDAG &DAG, bool isTailCall, unsigned ParamSize)
CalculateTailCallSPDiff - Get the amount the stack pointer has to be adjusted to accommodate the argu...
static Instruction * callIntrinsic(IRBuilderBase &Builder, Intrinsic::ID Id)
static void prepareIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, const SDLoc &dl)
static SDValue LowerLabelRef(SDValue HiPart, SDValue LoPart, bool isPIC, SelectionDAG &DAG)
static SDValue isScalarToVec(SDValue Op)
static SDValue widenVec(SelectionDAG &DAG, SDValue Vec, const SDLoc &dl)
static cl::opt< bool > DisablePerfectShuffle("ppc-disable-perfect-shuffle", cl::desc("disable vector permute decomposition"), cl::init(true), cl::Hidden)
bool isValidMtVsrBmi(APInt &BitMask, BuildVectorSDNode &BVN, bool IsLittleEndian)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value, SelectionDAG &DAG, const PPCSubtarget &STI)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static void PrepareTailCall(SelectionDAG &DAG, SDValue &InGlue, SDValue &Chain, const SDLoc &dl, int SPDiff, unsigned NumBytes, SDValue LROp, SDValue FPOp, SmallVectorImpl< TailCallArgumentInfo > &TailCallArguments)
static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, SDValue Chain, SDValue OldRetAddr, SDValue OldFP, int SPDiff, const SDLoc &dl)
EmitTailCallStoreFPAndRetAddr - Move the frame pointer and return address to the appropriate stack sl...
static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified amount.
static SDValue combineBVZEXTLOAD(SDNode *N, SelectionDAG &DAG)
static SDValue truncateScalarIntegerArg(ISD::ArgFlagsTy Flags, EVT ValVT, SelectionDAG &DAG, SDValue ArgValue, MVT LocVT, const SDLoc &dl)
static void computeFlagsForAddressComputation(SDValue N, unsigned &FlagSet, SelectionDAG &DAG)
Given a node, compute flags that are used for address computation when selecting load and store instr...
cl::opt< bool > ANDIGlueBug
static SDValue getOutputChainFromCallSeq(SDValue CallSeqStart)
static bool CalculateStackSlotUsed(EVT ArgVT, EVT OrigVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize, unsigned LinkageSize, unsigned ParamAreaSize, unsigned &ArgOffset, unsigned &AvailableFPRs, unsigned &AvailableVRs)
CalculateStackSlotUsed - Return whether this argument will use its stack slot (instead of being passe...
static cl::opt< unsigned > PPCAIXTLSModelOptUseIEForLDLimit("ppc-aix-shared-lib-tls-model-opt-limit", cl::init(1), cl::Hidden, cl::desc("Set inclusive limit count of TLS local-dynamic access(es) in a " "function to use initial-exec"))
static unsigned getPPCStrictOpcode(unsigned Opc)
static void prepareDescriptorIndirectCall(SelectionDAG &DAG, SDValue &Callee, SDValue &Glue, SDValue &Chain, SDValue CallSeqStart, const CallBase *CB, const SDLoc &dl, bool hasNest, const PPCSubtarget &Subtarget)
static 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)
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
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.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
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.
LLVM_ABI APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
void clearAllBits()
Set every bit to 0.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition)
Insert the bits from a smaller APInt starting at bitPosition.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
An arbitrary precision integer that knows its signedness.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ 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
This is an SDNode representing atomic operations.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
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.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign 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].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
LLVM_ABI unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
LLVM_ABI IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
LLVM_ABI Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
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.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
BasicBlock * GetInsertBlock() const
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateTruncOrBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
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 '...
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
MVT getScalarIntVT() const
bool useSoftFloat() const
const PPCFrameLowering * getFrameLowering() const override
bool needsSwapsForVSXMemOps() const
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
bool usesFunctionDescriptors() const
True if the ABI is descriptor based.
MCRegister getEnvironmentPointerRegister() const
const PPCInstrInfo * getInstrInfo() const override
unsigned getCPUDirective() const
getCPUDirective - Returns the -m directive specified for the cpu.
POPCNTDKind hasPOPCNTD() const
bool isLittleEndian() const
bool isTargetLinux() const
MCRegister getTOCPointerRegister() const
MCRegister getStackPointerRegister() const
bool is64BitELFABI() const
const PPCTargetMachine & getTargetMachine() const
bool isPredictableSelectIsExpensive() const
bool enableMachineScheduler() const override
Scheduling customization.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
unsigned descriptorEnvironmentPointerOffset() const
MachineBasicBlock * emitEHSjLjLongJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
CCAssignFn * ccAssignFnForCall(CallingConv::ID CC, bool Return, bool IsVarArg) const
bool isTruncateFree(Type *Ty1, Type *Ty2) const override
isTruncateFree - Return true if it's free to truncate a value of type Ty1 to type Ty2.
Value * emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI, Value *AlignedAddr, Value *Incr, Value *Mask, Value *ShiftAmt, AtomicOrdering Ord) const override
Perform a masked atomicrmw using a target-specific intrinsic.
MachineBasicBlock * EmitInstrWithCustomInserter(MachineInstr &MI, MachineBasicBlock *MBB) const override
This method should be implemented by targets that mark instructions with the 'usesCustomInserter' fla...
bool isFPExtFree(EVT DestVT, EVT SrcVT) const override
Return true if an fpext operation is free (for instance, because single-precision floating-point numb...
PPC::AddrMode SelectForceXFormMode(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
SelectForceXFormMode - Given the specified address, force it to be represented as an indexed [r+r] op...
Instruction * emitTrailingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
MachineBasicBlock * emitEHSjLjSetJmp(MachineInstr &MI, MachineBasicBlock *MBB) const
const char * getTargetNodeName(unsigned Opcode) const override
getTargetNodeName() - This method returns the name of a target specific DAG node.
bool supportsTailCallFor(const CallBase *CB) const
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override
Return true if folding a constant offset with the given GlobalAddress is legal.
MachineBasicBlock * emitProbedAlloca(MachineInstr &MI, MachineBasicBlock *MBB) const
bool isZExtFree(SDValue Val, EVT VT2) const override
Return true if zero-extending the specific node Val to type VT2 is free (either because it's implicit...
MachineBasicBlock * EmitPartwordAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, bool is8bit, unsigned Opcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const override
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
bool SelectAddressRegImm(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign EncodingAlignment) const
SelectAddressRegImm - Returns true if the address N can be represented by a base register plus a sign...
bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, MachineFunction &MF, unsigned Intrinsic) const override
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
SDValue expandVSXLoadForLE(SDNode *N, DAGCombinerInfo &DCI) const
bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, std::optional< CallingConv::ID > CC) const override
Target-specific splitting of values into parts that fit a register storing a legal type.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
LowerAsmOperandForConstraint - Lower the specified operand into the Ops vector.
void ReplaceNodeResults(SDNode *N, SmallVectorImpl< SDValue > &Results, SelectionDAG &DAG) const override
ReplaceNodeResults - Replace the results of node with an illegal result type with new values built ou...
bool hasMultipleConditionRegisters(EVT VT) const override
Does the target have multiple (allocatable) condition registers that can be used to store the results...
TargetLowering::AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
Align getByValTypeAlignment(Type *Ty, const DataLayout &DL) const override
getByValTypeAlignment - Return the desired alignment for ByVal aggregate function arguments in the ca...
bool SelectAddressRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG, MaybeAlign EncodingAlignment=std::nullopt) const
SelectAddressRegReg - Given the specified addressed, check to see if it can be more efficiently repre...
MachineBasicBlock * EmitAtomicBinary(MachineInstr &MI, MachineBasicBlock *MBB, unsigned AtomicSize, unsigned BinOpcode, unsigned CmpOpcode=0, unsigned CmpPred=0) const
SDValue BuildSDIVPow2(SDNode *N, const APInt &Divisor, SelectionDAG &DAG, SmallVectorImpl< SDNode * > &Created) const override
Targets may override this function to provide custom SDIV lowering for power-of-2 denominators.
Value * emitStoreConditional(IRBuilderBase &Builder, Value *Val, Value *Addr, AtomicOrdering Ord) const override
Perform a store-conditional operation to Addr.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
Value * emitLoadLinked(IRBuilderBase &Builder, Type *ValueTy, Value *Addr, AtomicOrdering Ord) const override
Perform a load-linked operation on Addr, returning a "Value *" with the corresponding pointee type.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(LLVMContext &Context, const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
unsigned getStackProbeSize(const MachineFunction &MF) const
PPCTargetLowering(const PPCTargetMachine &TM, const PPCSubtarget &STI)
TargetLowering::AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
bool useLoadStackGuardNode(const Module &M) const override
Override to support customized stack guard loading.
bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF, EVT VT) const override
isFMAFasterThanFMulAndFAdd - Return true if an FMA operation is faster than a pair of fmul and fadd i...
bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const override
Is unaligned memory access allowed for the given type, and is it fast relative to software emulation.
bool shouldExpandBuildVectorWithShuffles(EVT VT, unsigned DefinedValues) const override
bool SelectAddressRegImm34(SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG) const
Similar to the 16-bit case but for instructions that take a 34-bit displacement field (prefixed loads...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
Register getExceptionSelectorRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception typeid on entry to a la...
bool isJumpTableRelative() const override
Register getExceptionPointerRegister(const Constant *PersonalityFn) const override
If a physical register, this returns the register that receives the exception address on entry to an ...
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
LowerOperation - Provide custom lowering hooks for some operations.
PPC::AddrMode SelectOptimalAddrMode(const SDNode *Parent, SDValue N, SDValue &Disp, SDValue &Base, SelectionDAG &DAG, MaybeAlign Align) const
SelectOptimalAddrMode - Based on a node N and it's Parent (a MemSDNode), compute the address flags of...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
LLVM_ABI void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< value_op_iterator > op_values() const
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
LLVM_ABI SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
LLVM_ABI SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
LLVM_ABI SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=LocationSize::precise(0), const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
LLVM_ABI Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
LLVM_ABI SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
LLVM_ABI bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
LLVM_ABI SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
SDValue getTargetFrameIndex(int FI, EVT VT)
LLVM_ABI SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
LLVM_ABI bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
LLVM_ABI SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
LLVM_ABI void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
LLVM_ABI SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
LLVM_ABI SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
LLVM_ABI SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
LLVM_ABI SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
LLVM_ABI SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
LLVM_ABI SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
LLVM_ABI unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
LLVM_ABI SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
LLVM_ABI bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
LLVM_ABI SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVM_ABI SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
LLVM_ABI SDValue getCondCode(ISD::CondCode Cond)
LLVM_ABI bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
LLVM_ABI SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
LLVM_ABI SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
LLVM_ABI std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
LLVM_ABI SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setMinCmpXchgSizeInBits(unsigned SizeInBits)
Sets the minimum cmpxchg or ll/sc size supported by the backend.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
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 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
virtual bool isGAPlusOffset(SDNode *N, const GlobalValue *&GA, int64_t &Offset) const
Returns true (and the GlobalValue and the offset) if the node is a GlobalAddress + offset.
virtual unsigned getJumpTableEncoding() const
Return the entry encoding for a jump table in the current function.
Primary interface to the complete machine description for the target machine.
TLSModel::Model getTLSModel(const GlobalValue *GV) const
Returns the TLS model which should be used for the given global variable.
bool useEmulatedTLS() const
Returns true if this target uses emulated TLS.
Reloc::Model getRelocationModel() const
Returns the code generation relocation model.
bool shouldAssumeDSOLocal(const GlobalValue *GV) const
CodeModel::Model getCodeModel() const
Returns the code model.
unsigned UnsafeFPMath
UnsafeFPMath - This flag is enabled when the -enable-unsafe-fp-math flag is specified on the command ...
unsigned NoInfsFPMath
NoInfsFPMath - This flag is enabled when the -enable-no-infs-fp-math flag is specified on the command...
unsigned PPCGenScalarMASSEntries
Enables scalar MASS conversions.
unsigned NoNaNsFPMath
NoNaNsFPMath - This flag is enabled when the -enable-no-nans-fp-math flag is specified on the command...
unsigned GuaranteedTailCallOpt
GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
bool isVectorTy() const
True if this is an instance of VectorType.
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 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 IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
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.
int getNumOccurrences() const
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ Cold
Attempts to make code in the caller as efficient as possible under the assumption that the call is no...
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
@ MERGE_VALUES
MERGE_VALUES - This node takes multiple discrete operands and returns them all as its individual resu...
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ STRICT_FSETCC
STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used for floating-point operands only.
@ DELETED_NODE
DELETED_NODE - This is an illegal value that is used to catch errors.
@ EH_SJLJ_LONGJMP
OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer) This corresponds to the eh.sjlj.longjmp intrinsic.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
@ BSWAP
Byte Swap and Counting operators.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ SET_ROUNDING
Set rounding mode.
@ SIGN_EXTEND
Conversion operators.
@ SCALAR_TO_VECTOR
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
@ BR
Control flow instructions. These all have token chains.
@ PREFETCH
PREFETCH - This corresponds to a prefetch intrinsic.
@ FSINCOS
FSINCOS - Compute both fsin and fcos as a single operation.
@ FNEG
Perform various unary floating-point operations inspired by libm.
@ BR_CC
BR_CC - Conditional branch.
@ SSUBO
Same for subtraction.
@ BR_JT
BR_JT - Jumptable branch.
@ 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).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum maximum on two values, following IEEE-754 definition...
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ 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.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ ABDS
ABDS/ABDU - Absolute difference - Return the absolute difference between two numbers interpreted as s...
@ ADJUST_TRAMPOLINE
ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
@ INTRINSIC_W_CHAIN
RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...) This node represents a target in...
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
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.
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.
@ 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.
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.
Reg
All possible values of the reg field in the ModR/M byte.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
constexpr uint64_t PointerSize
aarch64 pointer size.
NodeAddr< FuncNode * > Func
LLVM_ABI const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
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.
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.
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 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)
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)
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
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.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
@ Mul
Product of integers.
@ Sub
Subtraction of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI)
Check if physical register Reg is used after MBI.
unsigned M0(unsigned Val)
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 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)
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI const fltSemantics & PPCDoubleDouble() LLVM_READNONE
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
LLVM_ABI Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
LLVM_ABI void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
LLVM_ABI SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)