69#include "llvm/IR/IntrinsicsPowerPC.h"
103#define DEBUG_TYPE "ppc-lowering"
106 "disable-p10-store-forward",
130 cl::desc(
"disable vector permute decomposition"),
134 "disable-auto-paired-vec-st",
135 cl::desc(
"disable automatically generated 32byte paired vector stores"),
140 cl::desc(
"Set minimum number of entries to use a jump table on PPC"));
144 cl::desc(
"max depth when checking alias info in GatherAllAliases()"));
148 cl::desc(
"Set inclusive limit count of TLS local-dynamic access(es) in a "
149 "function to use initial-exec"));
154 "Number of shuffles lowered to a VPERM or XXPERM");
155STATISTIC(NumDynamicAllocaProbed,
"Number of dynamic stack allocation probed");
178 initializeAddrModeMap();
181 bool isPPC64 = Subtarget.
isPPC64();
191 if (!Subtarget.hasEFPU2())
203 if (!Subtarget.hasP10Vector()) {
226 if (Subtarget.isISA3_0()) {
256 if (!Subtarget.hasSPE()) {
264 const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
265 for (
MVT VT : ScalarIntVTs) {
272 if (Subtarget.useCRBits()) {
275 if (isPPC64 || Subtarget.hasFPCVT()) {
341 if (Subtarget.isISA3_0()) {
376 if (!Subtarget.hasSPE()) {
381 if (Subtarget.hasVSX()) {
386 if (Subtarget.hasFSQRT()) {
391 if (Subtarget.hasFPRND()) {
432 if (Subtarget.hasSPE()) {
442 if (Subtarget.hasSPE())
446 if (!Subtarget.hasFSQRT() &&
447 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTE() &&
451 if (!Subtarget.hasFSQRT() &&
452 !(TM.Options.UnsafeFPMath && Subtarget.hasFRSQRTES() &&
453 Subtarget.hasFRES()))
456 if (Subtarget.hasFCPSGN()) {
464 if (Subtarget.hasFPRND()) {
478 if (Subtarget.isISA3_1()) {
484 (Subtarget.hasP9Vector() && isPPC64) ?
Custom :
Expand);
488 if (Subtarget.isISA3_0()) {
508 if (!Subtarget.useCRBits()) {
521 if (!Subtarget.useCRBits())
524 if (Subtarget.hasFPU()) {
535 if (!Subtarget.useCRBits())
540 if (Subtarget.hasSPE()) {
564 if (Subtarget.hasDirectMove() && isPPC64) {
569 if (TM.Options.UnsafeFPMath) {
672 if (Subtarget.hasSPE()) {
694 if (Subtarget.has64BitSupport()) {
709 if (Subtarget.hasLFIWAX() || isPPC64) {
715 if (Subtarget.hasSPE()) {
725 if (Subtarget.hasFPCVT()) {
726 if (Subtarget.has64BitSupport()) {
747 if (Subtarget.use64BitRegs()) {
765 if (Subtarget.has64BitSupport()) {
772 if (Subtarget.hasVSX()) {
779 if (Subtarget.hasAltivec()) {
780 for (
MVT VT : { MVT::v16i8, MVT::v8i16, MVT::v4i32 }) {
795 if (VT.getSizeInBits() <= 128 && VT.getScalarSizeInBits() <= 64) {
808 if (Subtarget.hasVSX()) {
814 if (Subtarget.hasP8Altivec() && (VT.SimpleTy != MVT::v1i128)) {
824 if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
898 if (!Subtarget.hasP8Vector()) {
940 if (Subtarget.hasAltivec())
941 for (
auto VT : {MVT::v4i32, MVT::v8i16, MVT::v16i8})
944 if (Subtarget.hasP8Altivec())
955 if (Subtarget.hasVSX()) {
961 if (Subtarget.hasP8Altivec())
966 if (Subtarget.isISA3_1()) {
1012 if (Subtarget.hasVSX()) {
1015 if (Subtarget.hasP8Vector()) {
1019 if (Subtarget.hasDirectMove() && isPPC64) {
1033 if (TM.Options.UnsafeFPMath) {
1070 if (Subtarget.hasP8Vector())
1079 if (Subtarget.hasP8Altivec()) {
1106 if (Subtarget.isISA3_1())
1209 if (Subtarget.hasP8Altivec()) {
1214 if (Subtarget.hasP9Vector()) {
1219 if (Subtarget.useCRBits()) {
1279 }
else if (Subtarget.hasVSX()) {
1304 for (
MVT VT : {MVT::f32, MVT::f64}) {
1323 if (Subtarget.hasP9Altivec()) {
1324 if (Subtarget.isISA3_1()) {
1347 if (Subtarget.hasP10Vector()) {
1352 if (Subtarget.pairedVectorMemops()) {
1357 if (Subtarget.hasMMA()) {
1358 if (Subtarget.isISAFuture())
1367 if (Subtarget.has64BitSupport())
1370 if (Subtarget.isISA3_1())
1388 if (Subtarget.hasAltivec()) {
1405 if (Subtarget.hasFPCVT())
1408 if (Subtarget.useCRBits())
1417 if (Subtarget.useCRBits()) {
1448 setLibcallName(RTLIB::MEMCPY, isPPC64 ?
"___memmove64" :
"___memmove");
1449 setLibcallName(RTLIB::MEMMOVE, isPPC64 ?
"___memmove64" :
"___memmove");
1450 setLibcallName(RTLIB::MEMSET, isPPC64 ?
"___memset64" :
"___memset");
1451 setLibcallName(RTLIB::BZERO, isPPC64 ?
"___bzero64" :
"___bzero");
1456 if (Subtarget.useCRBits()) {
1562void PPCTargetLowering::initializeAddrModeMap() {
1613 if (MaxAlign == MaxMaxAlign)
1615 if (
VectorType *VTy = dyn_cast<VectorType>(Ty)) {
1616 if (MaxMaxAlign >= 32 &&
1617 VTy->getPrimitiveSizeInBits().getFixedValue() >= 256)
1618 MaxAlign =
Align(32);
1619 else if (VTy->getPrimitiveSizeInBits().getFixedValue() >= 128 &&
1621 MaxAlign =
Align(16);
1622 }
else if (
ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1625 if (EltAlign > MaxAlign)
1626 MaxAlign = EltAlign;
1627 }
else if (
StructType *STy = dyn_cast<StructType>(Ty)) {
1628 for (
auto *EltTy : STy->elements()) {
1631 if (EltAlign > MaxAlign)
1632 MaxAlign = EltAlign;
1633 if (MaxAlign == MaxMaxAlign)
1646 if (Subtarget.hasAltivec())
1656 return Subtarget.hasSPE();
1664 Type *VectorTy,
unsigned ElemSizeInBits,
unsigned &Index)
const {
1665 if (!Subtarget.
isPPC64() || !Subtarget.hasVSX())
1668 if (
auto *VTy = dyn_cast<VectorType>(VectorTy)) {
1669 if (VTy->getScalarType()->isIntegerTy()) {
1671 if (ElemSizeInBits == 32) {
1675 if (ElemSizeInBits == 64) {
1701 return "PPCISD::FTSQRT";
1703 return "PPCISD::FSQRT";
1708 return "PPCISD::XXSPLTI_SP_TO_DP";
1710 return "PPCISD::XXSPLTI32DX";
1714 return "PPCISD::XXPERM";
1734 return "PPCISD::CALL_RM";
1736 return "PPCISD::CALL_NOP_RM";
1738 return "PPCISD::CALL_NOTOC_RM";
1743 return "PPCISD::BCTRL_RM";
1745 return "PPCISD::BCTRL_LOAD_TOC_RM";
1757 return "PPCISD::SCALAR_TO_VECTOR_PERMUTED";
1759 return "PPCISD::ANDI_rec_1_EQ_BIT";
1761 return "PPCISD::ANDI_rec_1_GT_BIT";
1776 return "PPCISD::ST_VSR_SCAL_INT";
1805 return "PPCISD::PADDI_DTPREL";
1821 return "PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR";
1823 return "PPCISD::TLS_LOCAL_EXEC_MAT_ADDR";
1833 return "PPCISD::STRICT_FADDRTZ";
1835 return "PPCISD::STRICT_FCTIDZ";
1837 return "PPCISD::STRICT_FCTIWZ";
1839 return "PPCISD::STRICT_FCTIDUZ";
1841 return "PPCISD::STRICT_FCTIWUZ";
1843 return "PPCISD::STRICT_FCFID";
1845 return "PPCISD::STRICT_FCFIDU";
1847 return "PPCISD::STRICT_FCFIDS";
1849 return "PPCISD::STRICT_FCFIDUS";
1852 return "PPCISD::STORE_COND";
1854 return "PPCISD::SETBC";
1856 return "PPCISD::SETBCR";
1864 return Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
1881 return CFP->getValueAPF().isZero();
1885 if (
const ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
1886 return CFP->getValueAPF().isZero();
1894 return Op < 0 ||
Op == Val;
1906 if (ShuffleKind == 0) {
1909 for (
unsigned i = 0; i != 16; ++i)
1912 }
else if (ShuffleKind == 2) {
1915 for (
unsigned i = 0; i != 16; ++i)
1918 }
else if (ShuffleKind == 1) {
1919 unsigned j = IsLE ? 0 : 1;
1920 for (
unsigned i = 0; i != 8; ++i)
1937 if (ShuffleKind == 0) {
1940 for (
unsigned i = 0; i != 16; i += 2)
1944 }
else if (ShuffleKind == 2) {
1947 for (
unsigned i = 0; i != 16; i += 2)
1951 }
else if (ShuffleKind == 1) {
1952 unsigned j = IsLE ? 0 : 2;
1953 for (
unsigned i = 0; i != 8; i += 2)
1974 if (!Subtarget.hasP8Vector())
1978 if (ShuffleKind == 0) {
1981 for (
unsigned i = 0; i != 16; i += 4)
1987 }
else if (ShuffleKind == 2) {
1990 for (
unsigned i = 0; i != 16; i += 4)
1996 }
else if (ShuffleKind == 1) {
1997 unsigned j = IsLE ? 0 : 4;
1998 for (
unsigned i = 0; i != 8; i += 4)
2015 unsigned LHSStart,
unsigned RHSStart) {
2016 if (
N->getValueType(0) != MVT::v16i8)
2018 assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
2019 "Unsupported merge size!");
2021 for (
unsigned i = 0; i != 8/UnitSize; ++i)
2022 for (
unsigned j = 0; j != UnitSize; ++j) {
2024 LHSStart+j+i*UnitSize) ||
2026 RHSStart+j+i*UnitSize))
2041 if (ShuffleKind == 1)
2043 else if (ShuffleKind == 2)
2048 if (ShuffleKind == 1)
2050 else if (ShuffleKind == 0)
2066 if (ShuffleKind == 1)
2068 else if (ShuffleKind == 2)
2073 if (ShuffleKind == 1)
2075 else if (ShuffleKind == 0)
2125 unsigned RHSStartValue) {
2126 if (
N->getValueType(0) != MVT::v16i8)
2129 for (
unsigned i = 0; i < 2; ++i)
2130 for (
unsigned j = 0; j < 4; ++j)
2132 i*RHSStartValue+j+IndexOffset) ||
2134 i*RHSStartValue+j+IndexOffset+8))
2156 unsigned indexOffset = CheckEven ? 4 : 0;
2157 if (ShuffleKind == 1)
2159 else if (ShuffleKind == 2)
2165 unsigned indexOffset = CheckEven ? 0 : 4;
2166 if (ShuffleKind == 1)
2168 else if (ShuffleKind == 0)
2184 if (
N->getValueType(0) != MVT::v16i8)
2191 for (i = 0; i != 16 && SVOp->
getMaskElt(i) < 0; ++i)
2194 if (i == 16)
return -1;
2199 if (ShiftAmt < i)
return -1;
2204 if ((ShuffleKind == 0 && !isLE) || (ShuffleKind == 2 && isLE)) {
2206 for (++i; i != 16; ++i)
2209 }
else if (ShuffleKind == 1) {
2211 for (++i; i != 16; ++i)
2218 ShiftAmt = 16 - ShiftAmt;
2227 EVT VT =
N->getValueType(0);
2228 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2229 return EltSize == 8 &&
N->getMaskElt(0) ==
N->getMaskElt(1);
2232 EltSize <= 8 &&
"Can only handle 1,2,4,8 byte element sizes");
2236 if (
N->getMaskElt(0) % EltSize != 0)
2241 unsigned ElementBase =
N->getMaskElt(0);
2244 if (ElementBase >= 16)
2249 for (
unsigned i = 1; i != EltSize; ++i)
2250 if (
N->getMaskElt(i) < 0 ||
N->getMaskElt(i) != (
int)(i+ElementBase))
2253 for (
unsigned i = EltSize, e = 16; i != e; i += EltSize) {
2254 if (
N->getMaskElt(i) < 0)
continue;
2255 for (
unsigned j = 0; j != EltSize; ++j)
2256 if (
N->getMaskElt(i+j) !=
N->getMaskElt(j))
2273 assert((Width == 2 || Width == 4 || Width == 8 || Width == 16) &&
2274 "Unexpected element width.");
2275 assert((StepLen == 1 || StepLen == -1) &&
"Unexpected element width.");
2277 unsigned NumOfElem = 16 / Width;
2278 unsigned MaskVal[16];
2279 for (
unsigned i = 0; i < NumOfElem; ++i) {
2280 MaskVal[0] =
N->getMaskElt(i * Width);
2281 if ((StepLen == 1) && (MaskVal[0] % Width)) {
2283 }
else if ((StepLen == -1) && ((MaskVal[0] + 1) % Width)) {
2287 for (
unsigned int j = 1; j < Width; ++j) {
2288 MaskVal[j] =
N->getMaskElt(i * Width + j);
2289 if (MaskVal[j] != MaskVal[j-1] + StepLen) {
2299 unsigned &InsertAtByte,
bool &Swap,
bool IsLE) {
2304 unsigned M0 =
N->getMaskElt(0) / 4;
2305 unsigned M1 =
N->getMaskElt(4) / 4;
2306 unsigned M2 =
N->getMaskElt(8) / 4;
2307 unsigned M3 =
N->getMaskElt(12) / 4;
2308 unsigned LittleEndianShifts[] = { 2, 1, 0, 3 };
2309 unsigned BigEndianShifts[] = { 3, 0, 1, 2 };
2314 if ((
M0 > 3 &&
M1 == 1 && M2 == 2 && M3 == 3) ||
2315 (
M0 < 4 &&
M1 == 5 && M2 == 6 && M3 == 7)) {
2316 ShiftElts = IsLE ? LittleEndianShifts[
M0 & 0x3] : BigEndianShifts[
M0 & 0x3];
2317 InsertAtByte = IsLE ? 12 : 0;
2322 if ((
M1 > 3 &&
M0 == 0 && M2 == 2 && M3 == 3) ||
2323 (
M1 < 4 &&
M0 == 4 && M2 == 6 && M3 == 7)) {
2324 ShiftElts = IsLE ? LittleEndianShifts[
M1 & 0x3] : BigEndianShifts[
M1 & 0x3];
2325 InsertAtByte = IsLE ? 8 : 4;
2330 if ((M2 > 3 &&
M0 == 0 &&
M1 == 1 && M3 == 3) ||
2331 (M2 < 4 &&
M0 == 4 &&
M1 == 5 && M3 == 7)) {
2332 ShiftElts = IsLE ? LittleEndianShifts[M2 & 0x3] : BigEndianShifts[M2 & 0x3];
2333 InsertAtByte = IsLE ? 4 : 8;
2338 if ((M3 > 3 &&
M0 == 0 &&
M1 == 1 && M2 == 2) ||
2339 (M3 < 4 &&
M0 == 4 &&
M1 == 5 && M2 == 6)) {
2340 ShiftElts = IsLE ? LittleEndianShifts[M3 & 0x3] : BigEndianShifts[M3 & 0x3];
2341 InsertAtByte = IsLE ? 0 : 12;
2348 if (
N->getOperand(1).isUndef()) {
2351 unsigned XXINSERTWSrcElem = IsLE ? 2 : 1;
2352 if (
M0 == XXINSERTWSrcElem &&
M1 == 1 && M2 == 2 && M3 == 3) {
2353 InsertAtByte = IsLE ? 12 : 0;
2356 if (
M0 == 0 &&
M1 == XXINSERTWSrcElem && M2 == 2 && M3 == 3) {
2357 InsertAtByte = IsLE ? 8 : 4;
2360 if (
M0 == 0 &&
M1 == 1 && M2 == XXINSERTWSrcElem && M3 == 3) {
2361 InsertAtByte = IsLE ? 4 : 8;
2364 if (
M0 == 0 &&
M1 == 1 && M2 == 2 && M3 == XXINSERTWSrcElem) {
2365 InsertAtByte = IsLE ? 0 : 12;
2374 bool &Swap,
bool IsLE) {
2375 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2381 unsigned M0 =
N->getMaskElt(0) / 4;
2382 unsigned M1 =
N->getMaskElt(4) / 4;
2383 unsigned M2 =
N->getMaskElt(8) / 4;
2384 unsigned M3 =
N->getMaskElt(12) / 4;
2388 if (
N->getOperand(1).isUndef()) {
2389 assert(
M0 < 4 &&
"Indexing into an undef vector?");
2390 if (
M1 != (
M0 + 1) % 4 || M2 != (
M1 + 1) % 4 || M3 != (M2 + 1) % 4)
2393 ShiftElts = IsLE ? (4 -
M0) % 4 :
M0;
2399 if (
M1 != (
M0 + 1) % 8 || M2 != (
M1 + 1) % 8 || M3 != (M2 + 1) % 8)
2403 if (
M0 == 0 ||
M0 == 7 ||
M0 == 6 ||
M0 == 5) {
2408 ShiftElts = (8 -
M0) % 8;
2409 }
else if (
M0 == 4 ||
M0 == 3 ||
M0 == 2 ||
M0 == 1) {
2414 ShiftElts = (4 -
M0) % 4;
2419 if (
M0 == 0 ||
M0 == 1 ||
M0 == 2 ||
M0 == 3) {
2424 }
else if (
M0 == 4 ||
M0 == 5 ||
M0 == 6 ||
M0 == 7) {
2436 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2441 for (
int i = 0; i < 16; i += Width)
2442 if (
N->getMaskElt(i) != i + Width - 1)
2473 bool &Swap,
bool IsLE) {
2474 assert(
N->getValueType(0) == MVT::v16i8 &&
"Shuffle vector expects v16i8");
2480 unsigned M0 =
N->getMaskElt(0) / 8;
2481 unsigned M1 =
N->getMaskElt(8) / 8;
2482 assert(((
M0 |
M1) < 4) &&
"A mask element out of bounds?");
2486 if (
N->getOperand(1).isUndef()) {
2487 if ((
M0 |
M1) < 2) {
2488 DM = IsLE ? (((~M1) & 1) << 1) + ((~
M0) & 1) : (
M0 << 1) + (
M1 & 1);
2496 if (
M0 > 1 &&
M1 < 2) {
2498 }
else if (M0 < 2 && M1 > 1) {
2506 DM = (((~M1) & 1) << 1) + ((~
M0) & 1);
2509 if (M0 < 2 && M1 > 1) {
2511 }
else if (
M0 > 1 &&
M1 < 2) {
2519 DM = (
M0 << 1) + (
M1 & 1);
2534 if (VT == MVT::v2i64 || VT == MVT::v2f64)
2539 return (16 / EltSize) - 1 - (SVOp->
getMaskElt(0) / EltSize);
2555 unsigned EltSize = 16/
N->getNumOperands();
2556 if (EltSize < ByteSize) {
2557 unsigned Multiple = ByteSize/EltSize;
2559 assert(Multiple > 1 && Multiple <= 4 &&
"How can this happen?");
2562 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2563 if (
N->getOperand(i).isUndef())
continue;
2565 if (!isa<ConstantSDNode>(
N->getOperand(i)))
return SDValue();
2567 if (!UniquedVals[i&(Multiple-1)].
getNode())
2568 UniquedVals[i&(Multiple-1)] =
N->getOperand(i);
2569 else if (UniquedVals[i&(Multiple-1)] !=
N->getOperand(i))
2579 bool LeadingZero =
true;
2580 bool LeadingOnes =
true;
2581 for (
unsigned i = 0; i != Multiple-1; ++i) {
2582 if (!UniquedVals[i].
getNode())
continue;
2589 if (!UniquedVals[Multiple-1].
getNode())
2596 if (!UniquedVals[Multiple-1].
getNode())
2598 int Val =cast<ConstantSDNode>(UniquedVals[Multiple-1])->getSExtValue();
2607 for (
unsigned i = 0, e =
N->getNumOperands(); i != e; ++i) {
2608 if (
N->getOperand(i).isUndef())
continue;
2610 OpVal =
N->getOperand(i);
2611 else if (OpVal !=
N->getOperand(i))
2617 unsigned ValSizeInBytes = EltSize;
2620 Value = CN->getZExtValue();
2622 assert(CN->getValueType(0) == MVT::f32 &&
"Only one legal FP vector type!");
2623 Value = llvm::bit_cast<uint32_t>(CN->getValueAPF().convertToFloat());
2629 if (ValSizeInBytes < ByteSize)
return SDValue();
2640 if (MaskVal == 0)
return SDValue();
2643 if (SignExtend32<5>(MaskVal) == MaskVal)
2657 if (!isa<ConstantSDNode>(
N))
2660 Imm = (int16_t)
N->getAsZExtVal();
2661 if (
N->getValueType(0) == MVT::i32)
2662 return Imm == (int32_t)
N->getAsZExtVal();
2664 return Imm == (int64_t)
N->getAsZExtVal();
2682 return (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0);
2690 for (
SDNode *U :
N->users()) {
2691 if (
MemSDNode *Memop = dyn_cast<MemSDNode>(U)) {
2692 if (Memop->getMemoryVT() == MVT::f64) {
2693 Base =
N.getOperand(0);
2694 Index =
N.getOperand(1);
2706 if (!isa<ConstantSDNode>(
N))
2709 Imm = (int64_t)cast<ConstantSDNode>(
N)->getSExtValue();
2710 return isInt<34>(Imm);
2737 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2742 Base =
N.getOperand(0);
2743 Index =
N.getOperand(1);
2745 }
else if (
N.getOpcode() ==
ISD::OR) {
2747 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm)))
2759 if (~(LHSKnown.
Zero | RHSKnown.
Zero) == 0) {
2760 Base =
N.getOperand(0);
2761 Index =
N.getOperand(1);
2831 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2837 Base =
N.getOperand(0);
2840 }
else if (
N.getOperand(1).getOpcode() ==
PPCISD::Lo) {
2842 assert(!
N.getOperand(1).getConstantOperandVal(1) &&
2843 "Cannot handle constant offsets yet!");
2844 Disp =
N.getOperand(1).getOperand(0);
2849 Base =
N.getOperand(0);
2852 }
else if (
N.getOpcode() ==
ISD::OR) {
2855 (!EncodingAlignment ||
isAligned(*EncodingAlignment, imm))) {
2865 dyn_cast<FrameIndexSDNode>(
N.getOperand(0))) {
2869 Base =
N.getOperand(0);
2882 (!EncodingAlignment ||
isAligned(*EncodingAlignment, Imm))) {
2885 CN->getValueType(0));
2890 if ((CN->getValueType(0) == MVT::i32 ||
2891 (int64_t)CN->getZExtValue() == (
int)CN->getZExtValue()) &&
2892 (!EncodingAlignment ||
2893 isAligned(*EncodingAlignment, CN->getZExtValue()))) {
2894 int Addr = (int)CN->getZExtValue();
2901 unsigned Opc = CN->
getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8;
2922 if (
N.getValueType() != MVT::i64)
2935 Base =
N.getOperand(0);
2951 Base =
N.getOperand(0);
2984 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
2985 Base =
N.getOperand(0);
2986 Index =
N.getOperand(1);
2998 Ty *PCRelCand = dyn_cast<Ty>(
N);
3010 if (isValidPCRelNode<ConstantPoolSDNode>(
N) ||
3011 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
3012 isValidPCRelNode<JumpTableSDNode>(
N) ||
3013 isValidPCRelNode<BlockAddressSDNode>(
N))
3029 EVT MemVT = LD->getMemoryVT();
3036 if (!ST.hasP8Vector())
3041 if (!ST.hasP9Vector())
3053 if (
Use.getResNo() == 0 &&
3075 Ptr = LD->getBasePtr();
3076 VT = LD->getMemoryVT();
3077 Alignment = LD->getAlign();
3078 }
else if (
StoreSDNode *ST = dyn_cast<StoreSDNode>(
N)) {
3079 Ptr = ST->getBasePtr();
3080 VT = ST->getMemoryVT();
3081 Alignment = ST->getAlign();
3104 if (isa<FrameIndexSDNode>(
Base) || isa<RegisterSDNode>(
Base))
3107 SDValue Val = cast<StoreSDNode>(
N)->getValue();
3120 if (VT != MVT::i64) {
3125 if (Alignment <
Align(4))
3135 if (LD->getValueType(0) == MVT::i64 && LD->getMemoryVT() == MVT::i32 &&
3137 isa<ConstantSDNode>(
Offset))
3152 unsigned &HiOpFlags,
unsigned &LoOpFlags,
3208 EVT PtrVT =
Op.getValueType();
3224 return getTOCEntry(DAG,
SDLoc(CP), GA);
3227 unsigned MOHiFlag, MOLoFlag;
3234 return getTOCEntry(DAG,
SDLoc(CP), GA);
3294 EVT PtrVT =
Op.getValueType();
3312 return getTOCEntry(DAG,
SDLoc(JT), GA);
3315 unsigned MOHiFlag, MOLoFlag;
3322 return getTOCEntry(DAG,
SDLoc(GA), GA);
3332 EVT PtrVT =
Op.getValueType();
3351 return getTOCEntry(DAG,
SDLoc(BASDN), GA);
3360 unsigned MOHiFlag, MOLoFlag;
3371 return LowerGlobalTLSAddressAIX(
Op, DAG);
3373 return LowerGlobalTLSAddressLinux(
Op, DAG);
3395 if (
I.getOpcode() == Instruction::Call)
3396 if (
const CallInst *CI = dyn_cast<const CallInst>(&
I))
3397 if (
Function *CF = CI->getCalledFunction())
3398 if (CF->isDeclaration() &&
3399 CF->getIntrinsicID() == Intrinsic::threadlocal_address)
3401 dyn_cast<GlobalValue>(
I.getOperand(0))) {
3407 unsigned TLSGVCnt = TLSGV.
size();
3417 <<
" function is using the TLS-IE model for TLS-LD access.\n");
3432 bool Is64Bit = Subtarget.
isPPC64();
3436 if (Subtarget.hasAIXShLibTLSModelOpt())
3446 bool HasAIXSmallLocalExecTLS = Subtarget.hasAIXSmallLocalExecTLS();
3447 bool HasAIXSmallTLSGlobalAttr =
false;
3450 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3454 if (GVar->hasAttribute(
"aix-small-tls"))
3455 HasAIXSmallTLSGlobalAttr =
true;
3474 if ((HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr) &&
3475 IsTLSLocalExecModel) {
3495 if (HasAIXSmallLocalExecTLS || HasAIXSmallTLSGlobalAttr)
3497 "currently only supported on AIX (64-bit mode).");
3503 bool HasAIXSmallLocalDynamicTLS = Subtarget.hasAIXSmallLocalDynamicTLS();
3507 if (!Is64Bit && HasAIXSmallLocalDynamicTLS)
3509 "currently only supported on AIX (64-bit mode).");
3517 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3521 dyn_cast_or_null<GlobalVariable>(
M->getOrInsertGlobal(
3524 assert(TLSGV &&
"Not able to create GV for _$TLSML.");
3527 SDValue ModuleHandleTOC = getTOCEntry(DAG, dl, ModuleHandleTGA);
3538 if (HasAIXSmallLocalDynamicTLS) {
3547 return DAG.
getNode(
ISD::ADD, dl, PtrVT, ModuleHandle, VariableOffset);
3560 SDValue VariableOffset = getTOCEntry(DAG, dl, VariableOffsetTGA);
3561 SDValue RegionHandle = getTOCEntry(DAG, dl, RegionHandleTGA);
3579 bool is64bit = Subtarget.
isPPC64();
3626 if (!
TM.isPositionIndependent())
3685 PtrVT, GOTPtr, TGA, TGA);
3687 PtrVT, TLSAddr, TGA);
3696 EVT PtrVT =
Op.getValueType();
3721 return getTOCEntry(DAG,
DL, GA);
3724 unsigned MOHiFlag, MOLoFlag;
3732 return getTOCEntry(DAG,
DL, GA);
3744 bool IsStrict =
Op->isStrictFPOpcode();
3746 cast<CondCodeSDNode>(
Op.getOperand(IsStrict ? 3 : 2))->get();
3750 EVT LHSVT =
LHS.getValueType();
3754 if (LHSVT == MVT::f128) {
3755 assert(!Subtarget.hasP9Vector() &&
3756 "SETCC for f128 is already legal under Power9!");
3767 assert(!IsStrict &&
"Don't know how to handle STRICT_FSETCC!");
3769 if (
Op.getValueType() == MVT::v2i64) {
3772 if (
LHS.getValueType() == MVT::v2i64) {
3780 int ShuffV[] = {1, 0, 3, 2};
3785 dl, MVT::v4i32, Shuff, SetCC32));
3802 if (
C->isAllOnes() ||
C->isZero())
3812 EVT VT =
Op.getValueType();
3821 EVT VT =
Node->getValueType(0);
3825 const Value *SV = cast<SrcValueSDNode>(
Node->getOperand(2))->getValue();
3835 if (VT == MVT::i64) {
3866 InChain = OverflowArea.
getValue(1);
3912 InChain = DAG.
getTruncStore(InChain, dl, OverflowArea, OverflowAreaPtr,
3919 assert(!Subtarget.
isPPC64() &&
"LowerVACOPY is PPC32 only");
3925 false,
true,
nullptr, std::nullopt,
3934 return Op.getOperand(0);
3943 "Expecting Inline ASM node.");
3953 if (
Op.getOperand(NumOps - 1).getValueType() == MVT::Glue)
3959 unsigned NumVals =
Flags.getNumOperandRegisters();
3962 switch (
Flags.getKind()) {
3973 for (; NumVals; --NumVals, ++i) {
3974 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
3975 if (Reg != PPC::LR && Reg != PPC::LR8)
4000 bool isPPC64 = (PtrVT == MVT::i64);
4006 Entry.Ty = IntPtrTy;
4007 Entry.Node = Trmp;
Args.push_back(Entry);
4012 Args.push_back(Entry);
4014 Entry.Node = FPtr;
Args.push_back(Entry);
4015 Entry.Node = Nest;
Args.push_back(Entry);
4019 CLI.setDebugLoc(dl).setChain(Chain).setLibCallee(
4023 std::pair<SDValue, SDValue> CallResult =
LowerCallTo(CLI);
4024 return CallResult.second;
4038 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4039 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
4074 uint64_t FrameOffset = PtrVT.getSizeInBits()/8;
4083 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
4098 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstStackOffset);
4101 SDValue thirdStore = DAG.
getStore(secondStore, dl, StackOffsetFI, nextPtr,
4103 nextOffset += FrameOffset;
4104 nextPtr = DAG.
getNode(
ISD::ADD, dl, PtrVT, nextPtr, ConstFrameOffset);
4107 return DAG.
getStore(thirdStore, dl, FR, nextPtr,
4113static const MCPhysReg FPR[] = {PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5,
4114 PPC::F6, PPC::F7, PPC::F8, PPC::F9, PPC::F10,
4115 PPC::F11, PPC::F12, PPC::F13};
4120 unsigned PtrByteSize) {
4122 if (Flags.isByVal())
4123 ArgSize = Flags.getByValSize();
4127 if (!Flags.isInConsecutiveRegs())
4128 ArgSize = ((ArgSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4137 unsigned PtrByteSize) {
4138 Align Alignment(PtrByteSize);
4141 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4142 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4143 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4144 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4145 Alignment =
Align(16);
4148 if (Flags.isByVal()) {
4149 auto BVAlign = Flags.getNonZeroByValAlign();
4150 if (BVAlign > PtrByteSize) {
4151 if (BVAlign.value() % PtrByteSize != 0)
4153 "ByVal alignment is not a multiple of the pointer size");
4155 Alignment = BVAlign;
4160 if (Flags.isInConsecutiveRegs()) {
4164 if (Flags.isSplit() && OrigVT != MVT::ppcf128)
4178 unsigned PtrByteSize,
unsigned LinkageSize,
4179 unsigned ParamAreaSize,
unsigned &ArgOffset,
4180 unsigned &AvailableFPRs,
4181 unsigned &AvailableVRs) {
4182 bool UseMemory =
false;
4187 ArgOffset =
alignTo(ArgOffset, Alignment);
4190 if (ArgOffset >= LinkageSize + ParamAreaSize)
4195 if (Flags.isInConsecutiveRegsLast())
4196 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4199 if (ArgOffset > LinkageSize + ParamAreaSize)
4204 if (!Flags.isByVal()) {
4205 if (ArgVT == MVT::f32 || ArgVT == MVT::f64)
4206 if (AvailableFPRs > 0) {
4210 if (ArgVT == MVT::v4f32 || ArgVT == MVT::v4i32 ||
4211 ArgVT == MVT::v8i16 || ArgVT == MVT::v16i8 ||
4212 ArgVT == MVT::v2f64 || ArgVT == MVT::v2i64 ||
4213 ArgVT == MVT::v1i128 || ArgVT == MVT::f128)
4214 if (AvailableVRs > 0) {
4226 unsigned NumBytes) {
4230SDValue PPCTargetLowering::LowerFormalArguments(
4235 return LowerFormalArguments_AIX(Chain, CallConv, isVarArg, Ins, dl, DAG,
4238 return LowerFormalArguments_64SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4241 return LowerFormalArguments_32SVR4(Chain, CallConv, isVarArg, Ins, dl, DAG,
4245SDValue PPCTargetLowering::LowerFormalArguments_32SVR4(
4287 const Align PtrAlign(4);
4296 CCInfo.AllocateStack(LinkageSize, PtrAlign);
4298 CCInfo.PreAnalyzeFormalArguments(Ins);
4301 CCInfo.clearWasPPCF128();
4303 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
4316 RC = &PPC::GPRCRegClass;
4319 if (Subtarget.hasP8Vector())
4320 RC = &PPC::VSSRCRegClass;
4321 else if (Subtarget.hasSPE())
4322 RC = &PPC::GPRCRegClass;
4324 RC = &PPC::F4RCRegClass;
4327 if (Subtarget.hasVSX())
4328 RC = &PPC::VSFRCRegClass;
4329 else if (Subtarget.hasSPE())
4331 RC = &PPC::GPRCRegClass;
4333 RC = &PPC::F8RCRegClass;
4338 RC = &PPC::VRRCRegClass;
4341 RC = &PPC::VRRCRegClass;
4345 RC = &PPC::VRRCRegClass;
4352 if (VA.
getLocVT() == MVT::f64 && Subtarget.hasSPE()) {
4353 assert(i + 1 < e &&
"No second half of double precision argument");
4365 ValVT == MVT::i1 ? MVT::i32 : ValVT);
4366 if (ValVT == MVT::i1)
4381 ArgOffset += ArgSize - ObjSize;
4399 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
4404 unsigned MinReservedArea = CCByValInfo.getStackSize();
4405 MinReservedArea = std::max(MinReservedArea, LinkageSize);
4421 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
4422 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
4424 const unsigned NumGPArgRegs = std::size(GPArgRegs);
4427 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
4430 unsigned NumFPArgRegs = std::size(FPArgRegs);
4439 int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 +
4443 PtrVT.getSizeInBits() / 8, CCInfo.getStackSize(),
true));
4452 for (
unsigned GPRIndex = 0; GPRIndex != NumGPArgRegs; ++GPRIndex) {
4456 VReg = MF.
addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass);
4471 for (
unsigned FPRIndex = 0; FPRIndex != NumFPArgRegs; ++FPRIndex) {
4475 VReg = MF.
addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass);
4488 if (!MemOps.
empty())
4499 const SDLoc &dl)
const {
4503 else if (
Flags.isZExt())
4510SDValue PPCTargetLowering::LowerFormalArguments_64SVR4(
4523 "fastcc not supported on varargs functions");
4529 unsigned PtrByteSize = 8;
4533 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4534 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4537 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4538 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4541 const unsigned Num_GPR_Regs = std::size(GPR);
4543 const unsigned Num_VR_Regs = std::size(VR);
4551 bool HasParameterArea = !isELFv2ABI || isVarArg;
4552 unsigned ParamAreaSize = Num_GPR_Regs * PtrByteSize;
4553 unsigned NumBytes = LinkageSize;
4554 unsigned AvailableFPRs = Num_FPR_Regs;
4555 unsigned AvailableVRs = Num_VR_Regs;
4556 for (
unsigned i = 0, e =
Ins.size(); i != e; ++i) {
4557 if (Ins[i].
Flags.isNest())
4561 PtrByteSize, LinkageSize, ParamAreaSize,
4562 NumBytes, AvailableFPRs, AvailableVRs))
4563 HasParameterArea =
true;
4570 unsigned ArgOffset = LinkageSize;
4571 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
4574 unsigned CurArgIdx = 0;
4575 for (
unsigned ArgNo = 0, e =
Ins.size(); ArgNo != e; ++ArgNo) {
4577 bool needsLoad =
false;
4578 EVT ObjectVT =
Ins[ArgNo].VT;
4579 EVT OrigVT =
Ins[ArgNo].ArgVT;
4581 unsigned ArgSize = ObjSize;
4583 if (Ins[ArgNo].isOrigArg()) {
4584 std::advance(FuncArg, Ins[ArgNo].getOrigArgIndex() - CurArgIdx);
4585 CurArgIdx =
Ins[ArgNo].getOrigArgIndex();
4590 unsigned CurArgOffset;
4592 auto ComputeArgOffset = [&]() {
4596 ArgOffset =
alignTo(ArgOffset, Alignment);
4597 CurArgOffset = ArgOffset;
4604 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4605 GPR_idx = std::min(GPR_idx, Num_GPR_Regs);
4610 if (
Flags.isByVal()) {
4611 assert(Ins[ArgNo].isOrigArg() &&
"Byval arguments cannot be implicit");
4617 ObjSize =
Flags.getByValSize();
4618 ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4640 if (HasParameterArea ||
4641 ArgSize + ArgOffset > LinkageSize + Num_GPR_Regs * PtrByteSize)
4648 if (ObjSize < PtrByteSize) {
4652 if (!isLittleEndian) {
4658 if (GPR_idx != Num_GPR_Regs) {
4670 ArgOffset += PtrByteSize;
4679 for (
unsigned j = 0;
j < ArgSize;
j += PtrByteSize) {
4680 if (GPR_idx == Num_GPR_Regs)
4691 unsigned StoreSizeInBits = std::min(PtrByteSize, (ObjSize - j)) * 8;
4699 ArgOffset += ArgSize;
4708 if (
Flags.isNest()) {
4713 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4714 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4722 if (GPR_idx != Num_GPR_Regs) {
4727 if (ObjectVT == MVT::i32 || ObjectVT == MVT::i1)
4730 ArgVal = extendArgForPPC64(Flags, ObjectVT, DAG, ArgVal, dl);
4736 ArgSize = PtrByteSize;
4747 if (FPR_idx != Num_FPR_Regs) {
4750 if (ObjectVT == MVT::f32)
4752 Subtarget.hasP8Vector()
4753 ? &PPC::VSSRCRegClass
4754 : &PPC::F4RCRegClass);
4757 ? &PPC::VSFRCRegClass
4758 : &PPC::F8RCRegClass);
4773 if (ObjectVT == MVT::f32) {
4774 if ((ArgOffset % PtrByteSize) == (isLittleEndian ? 4 : 0))
4792 ArgSize =
Flags.isInConsecutiveRegs() ? ObjSize : PtrByteSize;
4793 ArgOffset += ArgSize;
4794 if (
Flags.isInConsecutiveRegsLast())
4795 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
4809 if (VR_idx != Num_VR_Regs) {
4826 if (ObjSize < ArgSize && !isLittleEndian)
4827 CurArgOffset += ArgSize - ObjSize;
4837 unsigned MinReservedArea;
4838 if (HasParameterArea)
4839 MinReservedArea = std::max(ArgOffset, LinkageSize + 8 * PtrByteSize);
4841 MinReservedArea = LinkageSize;
4858 int Depth = ArgOffset;
4867 for (GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
4868 GPR_idx < Num_GPR_Regs; ++GPR_idx) {
4880 if (!MemOps.
empty())
4889 unsigned ParamSize) {
4891 if (!isTailCall)
return 0;
4895 int SPDiff = (int)CallerMinReservedArea - (
int)ParamSize;
4897 if (SPDiff < FI->getTailCallSPDelta())
4913 "PC Relative callers do not have a TOC and cannot share a TOC Base");
4926 if (!TM.shouldAssumeDSOLocal(CalleeGV))
4932 const Function *
F = dyn_cast<Function>(CalleeGV);
4933 const GlobalAlias *Alias = dyn_cast<GlobalAlias>(CalleeGV);
4938 F = dyn_cast<Function>(GlobalObj);
4971 if (TM.getFunctionSections() || CalleeGV->
hasComdat() ||
4972 Caller->hasComdat() || CalleeGV->
getSection() != Caller->getSection())
4974 if (
const auto *
F = dyn_cast<Function>(CalleeGV)) {
4975 if (
F->getSectionPrefix() != Caller->getSectionPrefix())
4987 const unsigned PtrByteSize = 8;
4991 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
4992 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
4995 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
4996 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
4999 const unsigned NumGPRs = std::size(GPR);
5000 const unsigned NumFPRs = 13;
5001 const unsigned NumVRs = std::size(VR);
5002 const unsigned ParamAreaSize = NumGPRs * PtrByteSize;
5004 unsigned NumBytes = LinkageSize;
5005 unsigned AvailableFPRs = NumFPRs;
5006 unsigned AvailableVRs = NumVRs;
5009 if (Param.Flags.isNest())
continue;
5012 LinkageSize, ParamAreaSize, NumBytes,
5013 AvailableFPRs, AvailableVRs))
5024 auto CalleeArgEnd = CB.
arg_end();
5027 for (; CalleeArgIter != CalleeArgEnd; ++CalleeArgIter, ++CallerArgIter) {
5028 const Value* CalleeArg = *CalleeArgIter;
5029 const Value* CallerArg = &(*CallerArgIter);
5030 if (CalleeArg == CallerArg)
5038 isa<UndefValue>(CalleeArg))
5056 if (!isTailCallableCC(CallerCC) || !isTailCallableCC(CalleeCC))
5066bool PPCTargetLowering::IsEligibleForTailCallOptimization_64SVR4(
5071 bool isCalleeExternalSymbol)
const {
5074 if (
DisableSCO && !TailCallOpt)
return false;
5077 if (isVarArg)
return false;
5153bool PPCTargetLowering::IsEligibleForTailCallOptimization(
5187 if (!
C)
return nullptr;
5189 int Addr =
C->getZExtValue();
5190 if ((
Addr & 3) != 0 ||
5196 (
int)
C->getZExtValue() >> 2,
SDLoc(
Op),
5203struct TailCallArgumentInfo {
5208 TailCallArgumentInfo() =
default;
5218 for (
unsigned i = 0, e = TailCallArgs.
size(); i != e; ++i) {
5219 SDValue Arg = TailCallArgs[i].Arg;
5220 SDValue FIN = TailCallArgs[i].FrameIdxOp;
5221 int FI = TailCallArgs[i].FrameIdx;
5224 Chain, dl, Arg, FIN,
5233 int SPDiff,
const SDLoc &dl) {
5239 int SlotSize = Subtarget.
isPPC64() ? 8 : 4;
5240 int NewRetAddrLoc = SPDiff + FL->getReturnSaveOffset();
5242 NewRetAddrLoc,
true);
5245 Chain = DAG.
getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx,
5255 int SPDiff,
unsigned ArgOffset,
5257 int Offset = ArgOffset + SPDiff;
5260 EVT VT = IsPPC64 ? MVT::i64 : MVT::i32;
5262 TailCallArgumentInfo
Info;
5264 Info.FrameIdxOp = FIN;
5272SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(
5277 LROpOut = getReturnAddrFrameIndex(DAG);
5296 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
false,
false,
5304 SDValue PtrOff,
int SPDiff,
unsigned ArgOffset,
bool isPPC64,
5328 const SDLoc &dl,
int SPDiff,
unsigned NumBytes,
SDValue LROp,
5338 if (!MemOpChains2.
empty())
5362SDValue PPCTargetLowering::LowerCallResult(
5370 CCRetInfo.AnalyzeCallResult(
5376 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
5382 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
5385 Chain =
Lo.getValue(1);
5386 InGlue =
Lo.getValue(2);
5390 Chain =
Hi.getValue(1);
5391 InGlue =
Hi.getValue(2);
5428 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5460 bool IsStrictFPCall =
false) {
5464 unsigned RetOpc = 0;
5489 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5495 if (IsStrictFPCall) {
5526 auto isLocalCallee = [&]() {
5531 !isa_and_nonnull<GlobalIFunc>(GV);
5542 const auto getAIXFuncEntryPointSymbolSDNode = [&](
const GlobalValue *GV) {
5552 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5555 const GlobalValue *GV = cast<GlobalAddressSDNode>(Callee)->getGlobal();
5558 assert(!isa<GlobalIFunc>(GV) &&
"IFunc is not supported on AIX.");
5559 return getAIXFuncEntryPointSymbolSDNode(GV);
5566 const char *SymName = S->getSymbol();
5572 dyn_cast_or_null<Function>(
Mod->getNamedValue(SymName)))
5573 return getAIXFuncEntryPointSymbolSDNode(
F);
5579 const auto getExternalFunctionEntryPointSymbol = [&](
StringRef SymName) {
5587 SymName = getExternalFunctionEntryPointSymbol(SymName)->getName().data();
5594 assert(Callee.getNode() &&
"What no callee?");
5600 "Expected a CALLSEQ_STARTSDNode.");
5617 SDValue MTCTROps[] = {Chain, Callee, Glue};
5618 EVT ReturnTypes[] = {MVT::Other, MVT::Glue};
5659 auto MMOFlags = Subtarget.hasInvariantFunctionDescriptors()
5678 SDValue LoadFuncPtr = DAG.
getLoad(RegVT, dl, LDChain, Callee, MPI,
5679 Alignment, MMOFlags);
5686 DAG.
getLoad(RegVT, dl, LDChain, AddTOC,
5693 DAG.
getLoad(RegVT, dl, LDChain, AddPtr,
5705 "Nest parameter is not supported on AIX.");
5721 SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass,
5724 const bool IsPPC64 = Subtarget.
isPPC64();
5773 for (
unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
5775 RegsToPass[i].second.getValueType()));
5792 assert(Mask &&
"Missing call preserved mask for calling convention");
5800SDValue PPCTargetLowering::FinishCall(
5815 if (!CFlags.IsIndirect)
5819 dl, CFlags.HasNest, Subtarget);
5829 if (CFlags.IsTailCall) {
5833 cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) ||
5836 isa<ConstantSDNode>(Callee) ||
5838 "Expecting a global address, external symbol, absolute value, "
5839 "register or an indirect tail call when PC Relative calls are "
5843 "Unexpected call opcode for a tail call.");
5850 std::array<EVT, 2> ReturnTypes = {{MVT::Other, MVT::Glue}};
5851 Chain = DAG.
getNode(CallOpc, dl, ReturnTypes, Ops);
5863 Chain = DAG.
getCALLSEQ_END(Chain, NumBytes, BytesCalleePops, Glue, dl);
5866 return LowerCallResult(Chain, Glue, CFlags.CallConv, CFlags.IsVarArg, Ins, dl,
5877 const GlobalValue *CalleeGV = dyn_cast<GlobalValue>(CalleeFunc);
5886 return isEligibleForTCO(CalleeGV, CalleeCC, CallerCC, CB,
5887 CalleeFunc->
isVarArg(), Outs, Ins, CallerFunc,
5891bool PPCTargetLowering::isEligibleForTCO(
5896 bool isCalleeExternalSymbol)
const {
5901 return IsEligibleForTailCallOptimization_64SVR4(
5902 CalleeGV, CalleeCC, CallerCC, CB, isVarArg, Outs, Ins, CallerFunc,
5903 isCalleeExternalSymbol);
5905 return IsEligibleForTailCallOptimization(CalleeGV, CalleeCC, CallerCC,
5928 auto *
G = dyn_cast<GlobalAddressSDNode>(Callee);
5930 bool IsCalleeExternalSymbol = isa<ExternalSymbolSDNode>(Callee);
5933 isEligibleForTCO(GV, CallConv, CallerCC, CB, isVarArg, Outs, Ins,
5947 isa<GlobalAddressSDNode>(Callee)) &&
5948 "Callee should be an llvm::Function object.");
5951 <<
"\nTCO callee: ");
5958 "site marked musttail");
5963 if (Subtarget.useLongCalls() && isa<GlobalAddressSDNode>(Callee) &&
5965 Callee = LowerGlobalAddress(Callee, DAG);
5968 CallConv, isTailCall, isVarArg, isPatchPoint,
5976 return LowerCall_AIX(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5981 return LowerCall_64SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5983 return LowerCall_32SVR4(Chain, Callee, CFlags, Outs, OutVals, Ins, dl, DAG,
5987SDValue PPCTargetLowering::LowerCall_32SVR4(
5998 const bool IsVarArg = CFlags.IsVarArg;
5999 const bool IsTailCall = CFlags.IsTailCall;
6005 const Align PtrAlign(4);
6030 CCInfo.PreAnalyzeCallOperands(Outs);
6036 unsigned NumArgs = Outs.
size();
6038 for (
unsigned i = 0; i != NumArgs; ++i) {
6039 MVT ArgVT = Outs[i].VT;
6043 if (Outs[i].IsFixed) {
6053 errs() <<
"Call operand #" << i <<
" has unhandled type "
6063 CCInfo.clearWasPPCF128();
6070 CCByValInfo.AllocateStack(CCInfo.getStackSize(), PtrAlign);
6077 unsigned NumBytes = CCByValInfo.getStackSize();
6091 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6102 bool seenFloatArg =
false;
6107 for (
unsigned i = 0, RealArgIdx = 0, j = 0, e = ArgLocs.
size();
6109 ++i, ++RealArgIdx) {
6111 SDValue Arg = OutVals[RealArgIdx];
6114 if (
Flags.isByVal()) {
6119 assert((j < ByValArgLocs.
size()) &&
"Index out of bounds!");
6142 Chain = CallSeqStart = NewCallSeqStart;
6161 if (Subtarget.hasSPE() && Arg.
getValueType() == MVT::f64) {
6168 RegsToPass.
push_back(std::make_pair(ArgLocs[++i].getLocReg(),
6192 if (!MemOpChains.
empty())
6198 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6199 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6200 RegsToPass[i].second, InGlue);
6208 SDValue Ops[] = { Chain, InGlue };
6220 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6221 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6226SDValue PPCTargetLowering::createMemcpyOutsideCallSeq(
6238 return NewCallSeqStart;
6241SDValue PPCTargetLowering::LowerCall_64SVR4(
6250 unsigned NumOps = Outs.
size();
6251 bool IsSibCall =
false;
6255 unsigned PtrByteSize = 8;
6270 assert(!(IsFastCall && CFlags.IsVarArg) &&
6271 "fastcc not supported on varargs functions");
6278 unsigned NumBytes = LinkageSize;
6279 unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0;
6282 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6283 PPC::X7, PPC::X8, PPC::X9, PPC::X10,
6286 PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8,
6287 PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13
6290 const unsigned NumGPRs = std::size(GPR);
6292 const unsigned NumVRs = std::size(VR);
6298 bool HasParameterArea = !isELFv2ABI || CFlags.IsVarArg || IsFastCall;
6299 if (!HasParameterArea) {
6300 unsigned ParamAreaSize = NumGPRs * PtrByteSize;
6301 unsigned AvailableFPRs = NumFPRs;
6302 unsigned AvailableVRs = NumVRs;
6303 unsigned NumBytesTmp = NumBytes;
6304 for (
unsigned i = 0; i != NumOps; ++i) {
6305 if (Outs[i].
Flags.isNest())
continue;
6307 PtrByteSize, LinkageSize, ParamAreaSize,
6308 NumBytesTmp, AvailableFPRs, AvailableVRs))
6309 HasParameterArea =
true;
6315 unsigned NumGPRsUsed = 0, NumFPRsUsed = 0, NumVRsUsed = 0;
6320 HasParameterArea =
false;
6323 for (
unsigned i = 0; i != NumOps; ++i) {
6325 EVT ArgVT = Outs[i].VT;
6326 EVT OrigVT = Outs[i].ArgVT;
6332 if (
Flags.isByVal()) {
6333 NumGPRsUsed += (
Flags.getByValSize()+7)/8;
6334 if (NumGPRsUsed > NumGPRs)
6335 HasParameterArea =
true;
6342 if (++NumGPRsUsed <= NumGPRs)
6352 if (++NumVRsUsed <= NumVRs)
6356 if (++NumVRsUsed <= NumVRs)
6361 if (++NumFPRsUsed <= NumFPRs)
6365 HasParameterArea =
true;
6372 NumBytes =
alignTo(NumBytes, Alignement);
6375 if (
Flags.isInConsecutiveRegsLast())
6376 NumBytes = ((NumBytes + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6379 unsigned NumBytesActuallyUsed = NumBytes;
6389 if (HasParameterArea)
6390 NumBytes = std::max(NumBytes, LinkageSize + 8 * PtrByteSize);
6392 NumBytes = LinkageSize;
6407 if (CFlags.IsTailCall)
6419 Chain = EmitTailCallLoadFPAndRetAddr(DAG, SPDiff, Chain, LROp, FPOp, dl);
6430 unsigned ArgOffset = LinkageSize;
6436 for (
unsigned i = 0; i != NumOps; ++i) {
6439 EVT ArgVT = Outs[i].VT;
6440 EVT OrigVT = Outs[i].ArgVT;
6449 auto ComputePtrOff = [&]() {
6453 ArgOffset =
alignTo(ArgOffset, Alignment);
6464 GPR_idx = (ArgOffset - LinkageSize) / PtrByteSize;
6465 GPR_idx = std::min(GPR_idx, NumGPRs);
6472 Arg = DAG.
getNode(ExtOp, dl, MVT::i64, Arg);
6478 if (
Flags.isByVal()) {
6496 EVT VT = (
Size==1) ? MVT::i8 : ((
Size==2) ? MVT::i16 : MVT::i32);
6497 if (GPR_idx != NumGPRs) {
6501 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6503 ArgOffset += PtrByteSize;
6508 if (GPR_idx == NumGPRs &&
Size < 8) {
6510 if (!isLittleEndian) {
6515 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6518 ArgOffset += PtrByteSize;
6527 if ((NumGPRs - GPR_idx) * PtrByteSize <
Size)
6528 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, PtrOff,
6533 if (
Size < 8 && GPR_idx != NumGPRs) {
6543 if (!isLittleEndian) {
6547 Chain = CallSeqStart = createMemcpyOutsideCallSeq(Arg, AddPtr,
6555 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6558 ArgOffset += PtrByteSize;
6564 for (
unsigned j=0;
j<
Size;
j+=PtrByteSize) {
6567 if (GPR_idx != NumGPRs) {
6568 unsigned LoadSizeInBits = std::min(PtrByteSize, (
Size - j)) * 8;
6574 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6575 ArgOffset += PtrByteSize;
6577 ArgOffset += ((
Size -
j + PtrByteSize-1)/PtrByteSize)*PtrByteSize;
6589 if (
Flags.isNest()) {
6591 RegsToPass.
push_back(std::make_pair(PPC::X11, Arg));
6598 if (GPR_idx != NumGPRs) {
6599 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Arg));
6604 assert(HasParameterArea &&
6605 "Parameter area must exist to pass an argument in memory.");
6607 true, CFlags.IsTailCall,
false, MemOpChains,
6608 TailCallArguments, dl);
6610 ArgOffset += PtrByteSize;
6613 ArgOffset += PtrByteSize;
6626 bool NeedGPROrStack = CFlags.IsVarArg || FPR_idx == NumFPRs;
6627 bool NeededLoad =
false;
6630 if (FPR_idx != NumFPRs)
6631 RegsToPass.
push_back(std::make_pair(
FPR[FPR_idx++], Arg));
6634 if (!NeedGPROrStack)
6636 else if (GPR_idx != NumGPRs && !IsFastCall) {
6650 }
else if (!
Flags.isInConsecutiveRegs()) {
6656 }
else if (ArgOffset % PtrByteSize != 0) {
6660 if (!isLittleEndian)
6665 }
else if (
Flags.isInConsecutiveRegsLast()) {
6668 if (!isLittleEndian)
6678 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], ArgVal));
6686 !isLittleEndian && !
Flags.isInConsecutiveRegs()) {
6691 assert(HasParameterArea &&
6692 "Parameter area must exist to pass an argument in memory.");
6694 true, CFlags.IsTailCall,
false, MemOpChains,
6695 TailCallArguments, dl);
6702 if (!IsFastCall || NeededLoad) {
6704 Flags.isInConsecutiveRegs()) ? 4 : 8;
6705 if (
Flags.isInConsecutiveRegsLast())
6706 ArgOffset = ((ArgOffset + PtrByteSize - 1)/PtrByteSize) * PtrByteSize;
6726 if (CFlags.IsVarArg) {
6727 assert(HasParameterArea &&
6728 "Parameter area must exist if we have a varargs call.");
6734 if (VR_idx != NumVRs) {
6738 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Load));
6741 for (
unsigned i=0; i<16; i+=PtrByteSize) {
6742 if (GPR_idx == NumGPRs)
6749 RegsToPass.
push_back(std::make_pair(GPR[GPR_idx++], Load));
6755 if (VR_idx != NumVRs) {
6756 RegsToPass.
push_back(std::make_pair(VR[VR_idx++], Arg));
6761 assert(HasParameterArea &&
6762 "Parameter area must exist to pass an argument in memory.");
6764 true, CFlags.IsTailCall,
true, MemOpChains,
6765 TailCallArguments, dl);
6776 assert((!HasParameterArea || NumBytesActuallyUsed == ArgOffset) &&
6777 "mismatch in size of parameter area");
6778 (void)NumBytesActuallyUsed;
6780 if (!MemOpChains.
empty())
6786 if (CFlags.IsIndirect) {
6790 assert(!CFlags.IsTailCall &&
"Indirect tails calls not supported");
6805 if (isELFv2ABI && !CFlags.IsPatchPoint)
6806 RegsToPass.
push_back(std::make_pair((
unsigned)PPC::X12, Callee));
6812 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
6813 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
6814 RegsToPass[i].second, InGlue);
6818 if (CFlags.IsTailCall && !IsSibCall)
6822 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
6823 Callee, SPDiff, NumBytes, Ins, InVals, CB);
6830 "Required alignment greater than stack alignment.");
6850 return RequiredAlign <= 8;
6855 return RequiredAlign <= 4;
6865 const bool IsPPC64 = Subtarget.
isPPC64();
6866 const unsigned PtrSize = IsPPC64 ? 8 : 4;
6867 const Align PtrAlign(PtrSize);
6868 const Align StackAlign(16);
6871 if (ValVT == MVT::f128)
6878 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
6879 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
6881 PPC::X3, PPC::X4, PPC::X5, PPC::X6,
6882 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
6885 PPC::V2, PPC::V3, PPC::V4, PPC::V5,
6886 PPC::V6, PPC::V7, PPC::V8, PPC::V9,
6887 PPC::V10, PPC::V11, PPC::V12, PPC::V13};
6893 if (ByValAlign > StackAlign)
6895 "16 are not supported.");
6898 const Align ObjAlign = ByValAlign > PtrAlign ? ByValAlign : PtrAlign;
6902 if (ByValSize == 0) {
6910 while (NextReg != GPRs.
size() &&
6916 assert(Reg &&
"Alocating register unexpectedly failed.");
6921 const unsigned StackSize =
alignTo(ByValSize, ObjAlign);
6942 assert(IsPPC64 &&
"PPC32 should have split i64 values.");
6971 for (
unsigned I = 0;
I < StoreSize;
I += PtrSize) {
6973 assert(FReg &&
"An FPR should be available when a GPR is reserved.");
7006 const unsigned VecSize = 16;
7007 const Align VecAlign(VecSize);
7027 while (NextRegIndex != GPRs.
size() &&
7032 assert(Reg &&
"Allocating register unexpectedly failed.");
7045 for (
unsigned I = 0;
I != VecSize;
I += PtrSize)
7057 if (NextRegIndex == GPRs.
size()) {
7066 if (GPRs[NextRegIndex] == PPC::R9) {
7073 assert(FirstReg && SecondReg &&
7074 "Allocating R9 or R10 unexpectedly failed.");
7088 for (
unsigned I = 0;
I != VecSize;
I += PtrSize) {
7090 assert(Reg &&
"Failed to allocated register for vararg vector argument");
7105 assert((IsPPC64 || SVT != MVT::i64) &&
7106 "i64 should have been split for 32-bit codegen.");
7114 return IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7116 return HasP8Vector ? &PPC::VSSRCRegClass : &PPC::F4RCRegClass;
7118 return HasVSX ? &PPC::VSFRCRegClass : &PPC::F8RCRegClass;
7126 return &PPC::VRRCRegClass;
7139 else if (Flags.isZExt())
7149 if (PPC::GPRCRegClass.
contains(Reg)) {
7150 assert(Reg >= PPC::R3 && Reg <= PPC::R10 &&
7151 "Reg must be a valid argument register!");
7152 return LASize + 4 * (Reg - PPC::R3);
7155 if (PPC::G8RCRegClass.
contains(Reg)) {
7156 assert(Reg >= PPC::X3 && Reg <= PPC::X10 &&
7157 "Reg must be a valid argument register!");
7158 return LASize + 8 * (Reg - PPC::X3);
7204SDValue PPCTargetLowering::LowerFormalArguments_AIX(
7211 "Unexpected calling convention!");
7221 const bool IsPPC64 = Subtarget.
isPPC64();
7222 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7234 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7235 uint64_t SaveStackPos = CCInfo.getStackSize();
7237 CCInfo.AnalyzeFormalArguments(Ins,
CC_AIX);
7248 bool ArgSignExt =
Ins[VA.
getValNo()].Flags.isSExt();
7260 LocVT.
SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7262 MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7274 unsigned StoreSize =
7276 SaveStackPos =
alignTo(SaveStackPos + StoreSize, PtrByteSize);
7279 auto HandleMemLoc = [&]() {
7282 assert((ValSize <= LocSize) &&
7283 "Object size is larger than size of MemLoc");
7286 if (LocSize > ValSize)
7287 CurArgOffset += LocSize - ValSize;
7289 const bool IsImmutable =
7321 assert(isVarArg &&
"Only use custom memloc for vararg.");
7324 const unsigned OriginalValNo = VA.
getValNo();
7325 (void)OriginalValNo;
7327 auto HandleCustomVecRegLoc = [&]() {
7328 assert(
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7329 "Missing custom RegLoc.");
7332 "Unexpected Val type for custom RegLoc.");
7334 "ValNo mismatch between custom MemLoc and RegLoc.");
7338 Subtarget.hasVSX()));
7345 HandleCustomVecRegLoc();
7346 HandleCustomVecRegLoc();
7350 if (
I !=
End && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom()) {
7352 "Only 2 custom RegLocs expected for 64-bit codegen.");
7353 HandleCustomVecRegLoc();
7354 HandleCustomVecRegLoc();
7398 const unsigned Size =
7410 if (
Flags.isByVal()) {
7416 const unsigned StackSize =
alignTo(
Flags.getByValSize(), PtrByteSize);
7425 IsPPC64 ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
7427 auto HandleRegLoc = [&, RegClass, LocVT](
const MCPhysReg PhysReg,
7440 CopyFrom.
getValue(1), dl, CopyFrom,
7450 for (;
Offset != StackSize && ArgLocs[
I].isRegLoc();
7453 "RegLocs should be for ByVal argument.");
7460 if (
Offset != StackSize) {
7462 "Expected MemLoc for remaining bytes.");
7463 assert(ArgLocs[
I].isMemLoc() &&
"Expected MemLoc for remaining bytes.");
7477 Subtarget.hasVSX()));
7494 const unsigned MinParameterSaveArea = 8 * PtrByteSize;
7496 unsigned CallerReservedArea = std::max<unsigned>(
7497 CCInfo.getStackSize(), LinkageSize + MinParameterSaveArea);
7503 CallerReservedArea =
7512 static const MCPhysReg GPR_32[] = {PPC::R3, PPC::R4, PPC::R5, PPC::R6,
7513 PPC::R7, PPC::R8, PPC::R9, PPC::R10};
7515 static const MCPhysReg GPR_64[] = {PPC::X3, PPC::X4, PPC::X5, PPC::X6,
7516 PPC::X7, PPC::X8, PPC::X9, PPC::X10};
7517 const unsigned NumGPArgRegs = std::size(IsPPC64 ? GPR_64 : GPR_32);
7522 for (
unsigned GPRIndex =
7523 (CCInfo.getStackSize() - LinkageSize) / PtrByteSize;
7524 GPRIndex < NumGPArgRegs; ++GPRIndex) {
7527 IsPPC64 ? MF.
addLiveIn(GPR_64[GPRIndex], &PPC::G8RCRegClass)
7528 : MF.
addLiveIn(GPR_32[GPRIndex], &PPC::GPRCRegClass);
7540 if (!MemOps.
empty())
7546SDValue PPCTargetLowering::LowerCall_AIX(
7559 "Unexpected calling convention!");
7561 if (CFlags.IsPatchPoint)
7568 AIXCCState CCInfo(CFlags.CallConv, CFlags.IsVarArg, MF, ArgLocs,
7576 const bool IsPPC64 = Subtarget.
isPPC64();
7578 const unsigned PtrByteSize = IsPPC64 ? 8 : 4;
7579 CCInfo.AllocateStack(LinkageSize,
Align(PtrByteSize));
7580 CCInfo.AnalyzeCallOperands(Outs,
CC_AIX);
7588 const unsigned MinParameterSaveAreaSize = 8 * PtrByteSize;
7589 const unsigned NumBytes = std::max<unsigned>(
7590 LinkageSize + MinParameterSaveAreaSize, CCInfo.getStackSize());
7606 for (
unsigned I = 0, E = ArgLocs.
size();
I != E;) {
7607 const unsigned ValNo = ArgLocs[
I].getValNo();
7611 if (
Flags.isByVal()) {
7612 const unsigned ByValSize =
Flags.getByValSize();
7620 auto GetLoad = [&](
EVT VT,
unsigned LoadOffset) {
7629 unsigned LoadOffset = 0;
7632 while (LoadOffset + PtrByteSize <= ByValSize && ArgLocs[
I].isRegLoc()) {
7635 LoadOffset += PtrByteSize;
7638 "Unexpected location for pass-by-value argument.");
7642 if (LoadOffset == ByValSize)
7646 assert(ArgLocs[
I].getValNo() == ValNo &&
7647 "Expected additional location for by-value argument.");
7649 if (ArgLocs[
I].isMemLoc()) {
7650 assert(LoadOffset < ByValSize &&
"Unexpected memloc for by-val arg.");
7655 Chain = CallSeqStart = createMemcpyOutsideCallSeq(
7661 CallSeqStart, MemcpyFlags, DAG, dl);
7670 const unsigned ResidueBytes = ByValSize % PtrByteSize;
7671 assert(ResidueBytes != 0 && LoadOffset + PtrByteSize > ByValSize &&
7672 "Unexpected register residue for by-value argument.");
7674 for (
unsigned Bytes = 0; Bytes != ResidueBytes;) {
7678 : ((
N == 2) ? MVT::i16 : (
N == 4 ? MVT::i32 : MVT::i64));
7688 "Unexpected load emitted during handling of pass-by-value "
7696 ResidueVal = ResidueVal ? DAG.
getNode(
ISD::OR, dl, PtrVT, ResidueVal,
7731 assert(CFlags.IsVarArg &&
"Custom MemLocs only used for Vector args.");
7739 const unsigned OriginalValNo = VA.
getValNo();
7741 unsigned LoadOffset = 0;
7742 auto HandleCustomVecRegLoc = [&]() {
7743 assert(
I != E &&
"Unexpected end of CCvalAssigns.");
7744 assert(ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7745 "Expected custom RegLoc.");
7748 "Custom MemLoc ValNo and custom RegLoc ValNo must match.");
7754 LoadOffset += PtrByteSize;
7760 HandleCustomVecRegLoc();
7761 HandleCustomVecRegLoc();
7763 if (
I != E && ArgLocs[
I].isRegLoc() && ArgLocs[
I].needsCustom() &&
7764 ArgLocs[
I].getValNo() == OriginalValNo) {
7766 "Only 2 custom RegLocs expected for 64-bit codegen.");
7767 HandleCustomVecRegLoc();
7768 HandleCustomVecRegLoc();
7786 "Unexpected register handling for calling convention.");
7792 "Custom register handling only expected for VarArg.");
7810 "Unexpected custom register for argument!");
7831 if (!MemOpChains.
empty())
7836 if (CFlags.IsIndirect) {
7837 assert(!CFlags.IsTailCall &&
"Indirect tail-calls not supported.");
7841 const unsigned TOCSaveOffset =
7857 for (
auto Reg : RegsToPass) {
7862 const int SPDiff = 0;
7863 return FinishCall(CFlags, dl, DAG, RegsToPass, InGlue, Chain, CallSeqStart,
7864 Callee, SPDiff, NumBytes, Ins, InVals, CB);
7874 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7875 return CCInfo.CheckReturn(
7890 CCInfo.AnalyzeReturn(Outs,
7899 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7903 SDValue Arg = OutVals[RealResIdx];
7918 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7941 RetOps.push_back(Glue);
7947PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7952 EVT IntVT =
Op.getValueType();
7956 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7958 SDValue Ops[2] = {Chain, FPSIdx};
7972 bool isPPC64 = Subtarget.
isPPC64();
7973 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7993 bool isPPC64 = Subtarget.
isPPC64();
8014PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8016 bool isPPC64 = Subtarget.
isPPC64();
8050 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8051 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8062 bool isPPC64 = Subtarget.
isPPC64();
8074 Op.getOperand(0),
Op.getOperand(1));
8081 Op.getOperand(0),
Op.getOperand(1));
8085 if (
Op.getValueType().isVector())
8086 return LowerVectorLoad(
Op, DAG);
8088 assert(
Op.getValueType() == MVT::i1 &&
8089 "Custom lowering only for i1 loads");
8102 BasePtr, MVT::i8, MMO);
8110 if (
Op.getOperand(1).getValueType().isVector())
8111 return LowerVectorStore(
Op, DAG);
8113 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8114 "Custom lowering only for i1 stores");
8133 assert(
Op.getValueType() == MVT::i1 &&
8134 "Custom lowering only for i1 results");
8162 EVT TrgVT =
Op.getValueType();
8175 !llvm::has_single_bit<uint32_t>(
8186 if (SrcSize == 256) {
8197 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8205 for (
unsigned i = 0; i < TrgNumElts; ++i)
8208 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8212 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8225 EVT ResVT =
Op.getValueType();
8226 EVT CmpVT =
Op.getOperand(0).getValueType();
8228 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8234 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8251 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8283 if (
LHS.getValueType() == MVT::f32)
8296 if (
LHS.getValueType() == MVT::f32)
8305 if (
LHS.getValueType() == MVT::f32)
8319 if (
Cmp.getValueType() == MVT::f32)
8329 if (
Cmp.getValueType() == MVT::f32)
8335 if (
Cmp.getValueType() == MVT::f32)
8341 if (
Cmp.getValueType() == MVT::f32)
8347 if (
Cmp.getValueType() == MVT::f32)
8380 bool IsStrict =
Op->isStrictFPOpcode();
8386 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8389 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8391 MVT DestTy =
Op.getSimpleValueType();
8392 assert(Src.getValueType().isFloatingPoint() &&
8393 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8394 DestTy == MVT::i64) &&
8395 "Invalid FP_TO_INT types");
8396 if (Src.getValueType() == MVT::f32) {
8400 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8401 Chain = Src.getValue(1);
8405 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8415 assert((IsSigned || Subtarget.hasFPCVT()) &&
8416 "i64 FP_TO_UINT is supported only with FPCVT");
8419 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8423 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8426 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8431void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8433 const SDLoc &dl)
const {
8437 bool IsStrict =
Op->isStrictFPOpcode();
8440 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8441 (IsSigned || Subtarget.hasFPCVT());
8443 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8452 Alignment =
Align(4);
8455 SDValue Ops[] = { Chain, Tmp, FIPtr };
8457 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8459 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8463 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8472 RLI.Alignment = Alignment;
8480 const SDLoc &dl)
const {
8483 if (
Op->isStrictFPOpcode())
8490 const SDLoc &dl)
const {
8491 bool IsStrict =
Op->isStrictFPOpcode();
8494 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8495 EVT SrcVT = Src.getValueType();
8496 EVT DstVT =
Op.getValueType();
8499 if (SrcVT == MVT::f128)
8500 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8504 if (SrcVT == MVT::ppcf128) {
8505 if (DstVT == MVT::i32) {
8510 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8521 {Op.getOperand(0), Lo, Hi}, Flags);
8524 {Res.getValue(1), Res}, Flags);
8530 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8554 {Chain, Src, FltOfs}, Flags);
8558 {Chain, Val}, Flags);
8561 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8579 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8580 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8583 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8585 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8586 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8597bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8602 if (
Op->isStrictFPOpcode())
8607 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8611 Op.getOperand(0).getValueType())) {
8613 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8618 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8619 LD->isNonTemporal())
8621 if (
LD->getMemoryVT() != MemVT)
8631 RLI.Ptr =
LD->getBasePtr();
8632 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8634 "Non-pre-inc AM on PPC?");
8639 RLI.Chain =
LD->getChain();
8640 RLI.MPI =
LD->getPointerInfo();
8641 RLI.IsDereferenceable =
LD->isDereferenceable();
8642 RLI.IsInvariant =
LD->isInvariant();
8643 RLI.Alignment =
LD->getAlign();
8644 RLI.AAInfo =
LD->getAAInfo();
8645 RLI.Ranges =
LD->getRanges();
8647 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8655void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8661 SDLoc dl(NewResChain);
8664 NewResChain, DAG.
getUNDEF(MVT::Other));
8666 "A new TF really is required here");
8675bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8676 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8683 if (!Subtarget.hasP9Vector() &&
8690 if (
Use.getResNo() != 0)
8713 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8717 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8720 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8721 if (
Op->isStrictFPOpcode()) {
8723 Chain =
Op.getOperand(0);
8725 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8727 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8735 const SDLoc &dl)
const {
8736 assert((
Op.getValueType() == MVT::f32 ||
8737 Op.getValueType() == MVT::f64) &&
8738 "Invalid floating point type as target of conversion");
8739 assert(Subtarget.hasFPCVT() &&
8740 "Int to FP conversions with direct moves require FPCVT");
8741 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8742 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8764 for (
unsigned i = 1; i < NumConcat; ++i)
8771 const SDLoc &dl)
const {
8772 bool IsStrict =
Op->isStrictFPOpcode();
8773 unsigned Opc =
Op.getOpcode();
8774 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8777 "Unexpected conversion type");
8778 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8779 "Supports conversions to v2f64/v4f32 only.");
8783 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8786 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8791 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8794 for (
unsigned i = 0; i < WideNumElts; ++i)
8797 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8798 int SaveElts = FourEltRes ? 4 : 2;
8800 for (
int i = 0; i < SaveElts; i++)
8801 ShuffV[i * Stride] = i;
8803 for (
int i = 1; i <= SaveElts; i++)
8804 ShuffV[i * Stride - 1] = i - 1;
8812 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8813 EVT ExtVT = Src.getValueType();
8814 if (Subtarget.hasP9Altivec())
8825 {Op.getOperand(0), Extend}, Flags);
8827 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8835 bool IsStrict =
Op->isStrictFPOpcode();
8836 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8841 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8843 EVT InVT = Src.getValueType();
8844 EVT OutVT =
Op.getValueType();
8847 return LowerINT_TO_FPVector(
Op, DAG, dl);
8850 if (
Op.getValueType() == MVT::f128)
8851 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8854 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8857 if (Src.getValueType() == MVT::i1) {
8869 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8870 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8871 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8873 assert((IsSigned || Subtarget.hasFPCVT()) &&
8874 "UINT_TO_FP is supported only with FPCVT");
8876 if (Src.getValueType() == MVT::i64) {
8888 if (
Op.getValueType() == MVT::f32 &&
8889 !Subtarget.hasFPCVT() &&
8930 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8931 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8932 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8933 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8934 }
else if (Subtarget.hasLFIWAX() &&
8935 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8938 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8939 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8942 Ops, MVT::i32, MMO);
8943 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8944 }
else if (Subtarget.hasFPCVT() &&
8945 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8948 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8949 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8952 Ops, MVT::i32, MMO);
8953 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8954 }
else if (((Subtarget.hasLFIWAX() &&
8956 (Subtarget.hasFPCVT() &&
8970 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8971 "Expected an i32 store");
8977 RLI.Alignment =
Align(4);
8981 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8982 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8985 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8986 Ops, MVT::i32, MMO);
8987 Chain =
Bits.getValue(1);
8993 Chain =
FP.getValue(1);
8995 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8999 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9008 assert(Src.getValueType() == MVT::i32 &&
9009 "Unhandled INT_TO_FP type in custom expander!");
9019 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9022 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9031 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
9032 "Expected an i32 store");
9038 RLI.Alignment =
Align(4);
9043 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9044 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9046 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9050 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
9053 "i32->FP without LFIWAX supported only on PPC64");
9062 Chain, dl, Ext64, FIdx,
9068 MVT::f64, dl, Chain, FIdx,
9076 Chain =
FP.getValue(1);
9077 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9081 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9097 if (
auto *CVal = dyn_cast<ConstantSDNode>(
Op.getOperand(1))) {
9099 assert(Mode < 4 &&
"Unsupported rounding mode!");
9100 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9101 if (Subtarget.isISA3_0())
9104 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9105 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9108 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9109 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9111 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9129 if (!Subtarget.isISA3_0()) {
9131 Chain =
MFFS.getValue(1);
9135 if (Subtarget.isISA3_0()) {
9140 PPC::RLDIMI, Dl, MVT::i64,
9145 NewFPSCR =
SDValue(InsertRN, 0);
9156 if (Subtarget.isISA3_0()) {
9164 PPC::RLWIMI, Dl, MVT::i32,
9165 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9166 DAG.getTargetConstant(30, Dl, MVT::i32),
9167 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9175 if (Subtarget.isISA3_0())
9181 PPC::MTFSF, Dl, MVT::Other,
9182 {DAG.
getConstant(255, Dl, MVT::i32,
true), NewFPSCR, Zero, Zero, Chain});
9209 EVT VT =
Op.getValueType();
9215 Chain =
MFFS.getValue(1);
9229 "Stack slot adjustment is valid only on big endian subtargets!");
9259 EVT VT =
Op.getValueType();
9263 VT ==
Op.getOperand(1).getValueType() &&
9283 SDValue OutOps[] = { OutLo, OutHi };
9288 EVT VT =
Op.getValueType();
9292 VT ==
Op.getOperand(1).getValueType() &&
9312 SDValue OutOps[] = { OutLo, OutHi };
9318 EVT VT =
Op.getValueType();
9321 VT ==
Op.getOperand(1).getValueType() &&
9341 SDValue OutOps[] = { OutLo, OutHi };
9348 EVT VT =
Op.getValueType();
9355 EVT AmtVT =
Z.getValueType();
9378 static const MVT VTys[] = {
9379 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9382 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9385 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9390 EVT CanonicalVT = VTys[SplatSize-1];
9403 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9404 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9413 EVT DestVT = MVT::Other) {
9414 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9423 EVT DestVT = MVT::Other) {
9426 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9438 for (
unsigned i = 0; i != 16; ++i)
9459 EVT VecVT = V->getValueType(0);
9460 bool RightType = VecVT == MVT::v2f64 ||
9461 (HasP8Vector && VecVT == MVT::v4f32) ||
9462 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9466 bool IsSplat =
true;
9467 bool IsLoad =
false;
9468 SDValue Op0 = V->getOperand(0);
9473 if (V->isConstant())
9475 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9476 if (V->getOperand(i).isUndef())
9480 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9482 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9484 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9486 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9490 if (V->getOperand(i) != Op0 ||
9491 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9494 return !(IsSplat && IsLoad);
9504 (
Op.getValueType() != MVT::f128))
9509 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9529 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9537 APFloat APFloatToConvert = ArgAPFloat;
9538 bool LosesInfo =
true;
9543 ArgAPFloat = APFloatToConvert;
9565 APFloat APFloatToConvert = ArgAPFloat;
9566 bool LosesInfo =
true;
9570 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9575 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9579 EVT Ty =
Op->getValueType(0);
9582 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9591 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9595 if (Ty == MVT::v2i64) {
9598 if (MemVT == MVT::i32) {
9618 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9621 APInt APSplatBits, APSplatUndef;
9622 unsigned SplatBitSize;
9624 bool BVNIsConstantSplat =
9632 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9633 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9636 if ((
Op->getValueType(0) == MVT::v2f64) &&
9669 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9676 const SDValue *InputLoad = &
Op.getOperand(0);
9681 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9682 unsigned ElementSize =
9685 assert(((ElementSize == 2 * MemorySize)
9689 "Unmatched element size and opcode!\n");
9694 unsigned NumUsesOfInputLD = 128 / ElementSize;
9696 if (BVInOp.isUndef())
9711 if (NumUsesOfInputLD == 1 &&
9714 Subtarget.hasLFIWAX()))
9723 Subtarget.isISA3_1() && ElementSize <= 16)
9726 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9728 Subtarget.hasVSX()) {
9735 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9736 LD->getMemoryVT(),
LD->getMemOperand());
9748 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9750 Subtarget.hasP8Vector()))
9757 unsigned SplatSize = SplatBitSize / 8;
9762 if (SplatBits == 0) {
9764 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9776 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9778 Op.getValueType(), DAG, dl);
9780 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9785 if (Subtarget.hasP9Vector() && SplatSize == 1)
9790 int32_t SextVal =
SignExtend32(SplatBits, SplatBitSize);
9791 if (SextVal >= -16 && SextVal <= 15)
9804 if (SextVal >= -32 && SextVal <= 31) {
9809 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9810 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9813 if (VT ==
Op.getValueType())
9822 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9836 static const signed char SplatCsts[] = {
9837 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9838 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9841 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9844 int i = SplatCsts[idx];
9848 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9851 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9853 static const unsigned IIDs[] = {
9854 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9855 Intrinsic::ppc_altivec_vslw
9862 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9864 static const unsigned IIDs[] = {
9865 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9866 Intrinsic::ppc_altivec_vsrw
9873 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9874 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9876 static const unsigned IIDs[] = {
9877 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9878 Intrinsic::ppc_altivec_vrlw
9885 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9891 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9897 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9912 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9913 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9914 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9930 if (LHSID == (1*9+2)*9+3)
return LHS;
9931 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9943 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9944 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9945 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9946 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9949 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9950 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9951 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9952 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9955 for (
unsigned i = 0; i != 16; ++i)
9956 ShufIdxs[i] = (i&3)+0;
9959 for (
unsigned i = 0; i != 16; ++i)
9960 ShufIdxs[i] = (i&3)+4;
9963 for (
unsigned i = 0; i != 16; ++i)
9964 ShufIdxs[i] = (i&3)+8;
9967 for (
unsigned i = 0; i != 16; ++i)
9968 ShufIdxs[i] = (i&3)+12;
9989 const unsigned BytesInVector = 16;
9994 unsigned ShiftElts = 0, InsertAtByte = 0;
9998 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9999 0, 15, 14, 13, 12, 11, 10, 9};
10000 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10001 1, 2, 3, 4, 5, 6, 7, 8};
10004 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10016 bool FoundCandidate =
false;
10020 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10023 for (
unsigned i = 0; i < BytesInVector; ++i) {
10024 unsigned CurrentElement =
Mask[i];
10027 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
10030 bool OtherElementsInOrder =
true;
10033 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10040 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10041 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10042 OtherElementsInOrder =
false;
10049 if (OtherElementsInOrder) {
10051 if (
V2.isUndef()) {
10056 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10057 : BigEndianShifts[CurrentElement & 0xF];
10058 Swap = CurrentElement < BytesInVector;
10060 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10061 FoundCandidate =
true;
10066 if (!FoundCandidate)
10090 const unsigned NumHalfWords = 8;
10091 const unsigned BytesInVector = NumHalfWords * 2;
10100 unsigned ShiftElts = 0, InsertAtByte = 0;
10104 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10105 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10108 uint32_t OriginalOrderLow = 0x1234567;
10109 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10112 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10113 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10130 bool FoundCandidate =
false;
10133 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10134 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10142 if (
V2.isUndef()) {
10144 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10145 TargetOrder = OriginalOrderLow;
10149 if (MaskOneElt == VINSERTHSrcElem &&
10150 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10151 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10152 FoundCandidate =
true;
10158 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10160 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10162 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10163 : BigEndianShifts[MaskOneElt & 0x7];
10164 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10165 Swap = MaskOneElt < NumHalfWords;
10166 FoundCandidate =
true;
10172 if (!FoundCandidate)
10207 auto ShuffleMask = SVN->
getMask();
10222 ShuffleMask = CommutedSV->
getMask();
10231 APInt APSplatValue, APSplatUndef;
10232 unsigned SplatBitSize;
10248 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10249 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10250 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10252 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10253 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10254 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10262 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10263 SplatVal |= (SplatVal << SplatBitSize);
10277 assert(
Op.getValueType() == MVT::v1i128 &&
10278 "Only set v1i128 as custom, other type shouldn't reach here!");
10283 if (SHLAmt % 8 == 0) {
10284 std::array<int, 16>
Mask;
10285 std::iota(
Mask.begin(),
Mask.end(), 0);
10286 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10315 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10316 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10319 SVOp = cast<ShuffleVectorSDNode>(
Op);
10320 V1 =
Op.getOperand(0);
10321 V2 =
Op.getOperand(1);
10323 EVT VT =
Op.getValueType();
10326 unsigned ShiftElts, InsertAtByte;
10332 bool IsPermutedLoad =
false;
10334 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10344 if (IsPermutedLoad) {
10345 assert((isLittleEndian || IsFourByte) &&
10346 "Unexpected size for permuted load on big endian target");
10347 SplatIdx += IsFourByte ? 2 : 1;
10348 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10349 "Splat of a value outside of the loaded memory");
10354 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10357 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10359 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10363 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10376 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10379 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10388 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10391 if (Subtarget.hasP9Vector() &&
10412 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10414 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10415 return SplatInsertNode;
10418 if (Subtarget.hasP9Altivec()) {
10420 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10423 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10427 if (Subtarget.hasVSX() &&
10440 if (Subtarget.hasVSX() &&
10453 if (Subtarget.hasP9Vector()) {
10473 if (Subtarget.hasVSX()) {
10494 if (
V2.isUndef()) {
10507 (Subtarget.hasP8Altivec() && (
10518 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10528 (Subtarget.hasP8Altivec() && (
10539 unsigned PFIndexes[4];
10540 bool isFourElementShuffle =
true;
10541 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10543 unsigned EltNo = 8;
10544 for (
unsigned j = 0;
j != 4; ++
j) {
10545 if (PermMask[i * 4 + j] < 0)
10548 unsigned ByteSource = PermMask[i * 4 +
j];
10549 if ((ByteSource & 3) != j) {
10550 isFourElementShuffle =
false;
10555 EltNo = ByteSource / 4;
10556 }
else if (EltNo != ByteSource / 4) {
10557 isFourElementShuffle =
false;
10561 PFIndexes[i] = EltNo;
10569 if (isFourElementShuffle) {
10571 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10572 PFIndexes[2] * 9 + PFIndexes[3];
10575 unsigned Cost = (PFEntry >> 30);
10595 if (
V2.isUndef())
V2 = V1;
10597 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10606 bool NeedSwap =
false;
10608 bool isPPC64 = Subtarget.
isPPC64();
10610 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10612 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10613 "XXPERM instead\n");
10619 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10620 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10622 NeedSwap = !NeedSwap;
10657 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10659 if (V1HasXXSWAPD) {
10662 else if (SrcElt < 16)
10665 if (V2HasXXSWAPD) {
10668 else if (SrcElt > 15)
10677 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10678 if (isLittleEndian)
10680 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10683 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10686 if (V1HasXXSWAPD) {
10690 if (V2HasXXSWAPD) {
10691 dl =
SDLoc(
V2->getOperand(0));
10692 V2 =
V2->getOperand(0)->getOperand(1);
10695 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10696 if (ValType != MVT::v2f64)
10698 if (
V2.getValueType() != MVT::v2f64)
10702 ShufflesHandledWithVPERM++;
10707 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10709 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10712 dbgs() <<
"With the following permute control vector:\n";
10717 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10721 if (isLittleEndian)
10727 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10739 switch (IntrinsicID) {
10743 case Intrinsic::ppc_altivec_vcmpbfp_p:
10747 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10751 case Intrinsic::ppc_altivec_vcmpequb_p:
10755 case Intrinsic::ppc_altivec_vcmpequh_p:
10759 case Intrinsic::ppc_altivec_vcmpequw_p:
10763 case Intrinsic::ppc_altivec_vcmpequd_p:
10764 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10770 case Intrinsic::ppc_altivec_vcmpneb_p:
10771 case Intrinsic::ppc_altivec_vcmpneh_p:
10772 case Intrinsic::ppc_altivec_vcmpnew_p:
10773 case Intrinsic::ppc_altivec_vcmpnezb_p:
10774 case Intrinsic::ppc_altivec_vcmpnezh_p:
10775 case Intrinsic::ppc_altivec_vcmpnezw_p:
10776 if (Subtarget.hasP9Altivec()) {
10777 switch (IntrinsicID) {
10780 case Intrinsic::ppc_altivec_vcmpneb_p:
10783 case Intrinsic::ppc_altivec_vcmpneh_p:
10786 case Intrinsic::ppc_altivec_vcmpnew_p:
10789 case Intrinsic::ppc_altivec_vcmpnezb_p:
10792 case Intrinsic::ppc_altivec_vcmpnezh_p:
10795 case Intrinsic::ppc_altivec_vcmpnezw_p:
10803 case Intrinsic::ppc_altivec_vcmpgefp_p:
10807 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10811 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10815 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10819 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10823 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10824 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10830 case Intrinsic::ppc_altivec_vcmpgtub_p:
10834 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10838 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10842 case Intrinsic::ppc_altivec_vcmpgtud_p:
10843 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10850 case Intrinsic::ppc_altivec_vcmpequq:
10851 case Intrinsic::ppc_altivec_vcmpgtsq:
10852 case Intrinsic::ppc_altivec_vcmpgtuq:
10853 if (!Subtarget.isISA3_1())
10855 switch (IntrinsicID) {
10858 case Intrinsic::ppc_altivec_vcmpequq:
10861 case Intrinsic::ppc_altivec_vcmpgtsq:
10864 case Intrinsic::ppc_altivec_vcmpgtuq:
10871 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10872 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10873 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10874 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10875 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10876 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10877 if (Subtarget.hasVSX()) {
10878 switch (IntrinsicID) {
10879 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10882 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10885 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10888 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10891 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10894 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10904 case Intrinsic::ppc_altivec_vcmpbfp:
10907 case Intrinsic::ppc_altivec_vcmpeqfp:
10910 case Intrinsic::ppc_altivec_vcmpequb:
10913 case Intrinsic::ppc_altivec_vcmpequh:
10916 case Intrinsic::ppc_altivec_vcmpequw:
10919 case Intrinsic::ppc_altivec_vcmpequd:
10920 if (Subtarget.hasP8Altivec())
10925 case Intrinsic::ppc_altivec_vcmpneb:
10926 case Intrinsic::ppc_altivec_vcmpneh:
10927 case Intrinsic::ppc_altivec_vcmpnew:
10928 case Intrinsic::ppc_altivec_vcmpnezb:
10929 case Intrinsic::ppc_altivec_vcmpnezh:
10930 case Intrinsic::ppc_altivec_vcmpnezw:
10931 if (Subtarget.hasP9Altivec())
10932 switch (IntrinsicID) {
10935 case Intrinsic::ppc_altivec_vcmpneb:
10938 case Intrinsic::ppc_altivec_vcmpneh:
10941 case Intrinsic::ppc_altivec_vcmpnew:
10944 case Intrinsic::ppc_altivec_vcmpnezb:
10947 case Intrinsic::ppc_altivec_vcmpnezh:
10950 case Intrinsic::ppc_altivec_vcmpnezw:
10957 case Intrinsic::ppc_altivec_vcmpgefp:
10960 case Intrinsic::ppc_altivec_vcmpgtfp:
10963 case Intrinsic::ppc_altivec_vcmpgtsb:
10966 case Intrinsic::ppc_altivec_vcmpgtsh:
10969 case Intrinsic::ppc_altivec_vcmpgtsw:
10972 case Intrinsic::ppc_altivec_vcmpgtsd:
10973 if (Subtarget.hasP8Altivec())
10978 case Intrinsic::ppc_altivec_vcmpgtub:
10981 case Intrinsic::ppc_altivec_vcmpgtuh:
10984 case Intrinsic::ppc_altivec_vcmpgtuw:
10987 case Intrinsic::ppc_altivec_vcmpgtud:
10988 if (Subtarget.hasP8Altivec())
10993 case Intrinsic::ppc_altivec_vcmpequq_p:
10994 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10995 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10996 if (!Subtarget.isISA3_1())
10998 switch (IntrinsicID) {
11001 case Intrinsic::ppc_altivec_vcmpequq_p:
11004 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11007 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11021 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11025 switch (IntrinsicID) {
11026 case Intrinsic::thread_pointer:
11032 case Intrinsic::ppc_rldimi: {
11033 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
11037 return Op.getOperand(2);
11038 if (
Mask.isAllOnes())
11041 unsigned MB = 0, ME = 0;
11045 if (ME < 63 - SH) {
11048 }
else if (ME > 63 - SH) {
11054 {Op.getOperand(2), Src,
11055 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11056 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11060 case Intrinsic::ppc_rlwimi: {
11063 return Op.getOperand(2);
11064 if (
Mask.isAllOnes())
11067 unsigned MB = 0, ME = 0;
11071 PPC::RLWIMI, dl, MVT::i32,
11072 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11073 DAG.getTargetConstant(MB, dl, MVT::i32),
11074 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11078 case Intrinsic::ppc_rlwnm: {
11079 if (
Op.getConstantOperandVal(3) == 0)
11081 unsigned MB = 0, ME = 0;
11086 {Op.getOperand(1), Op.getOperand(2),
11087 DAG.getTargetConstant(MB, dl, MVT::i32),
11088 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11092 case Intrinsic::ppc_mma_disassemble_acc: {
11093 if (Subtarget.isISAFuture()) {
11094 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11132 case Intrinsic::ppc_vsx_disassemble_pair: {
11135 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11140 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11151 case Intrinsic::ppc_mma_xxmfacc:
11152 case Intrinsic::ppc_mma_xxmtacc: {
11154 if (!Subtarget.isISAFuture())
11165 case Intrinsic::ppc_unpack_longdouble: {
11166 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11167 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11168 "Argument of long double unpack must be 0 or 1!");
11171 Idx->getValueType(0)));
11174 case Intrinsic::ppc_compare_exp_lt:
11175 case Intrinsic::ppc_compare_exp_gt:
11176 case Intrinsic::ppc_compare_exp_eq:
11177 case Intrinsic::ppc_compare_exp_uo: {
11179 switch (IntrinsicID) {
11180 case Intrinsic::ppc_compare_exp_lt:
11183 case Intrinsic::ppc_compare_exp_gt:
11186 case Intrinsic::ppc_compare_exp_eq:
11189 case Intrinsic::ppc_compare_exp_uo:
11195 PPC::SELECT_CC_I4, dl, MVT::i32,
11196 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11197 Op.getOperand(1), Op.getOperand(2)),
11199 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11200 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11203 case Intrinsic::ppc_test_data_class: {
11204 EVT OpVT =
Op.getOperand(1).getValueType();
11205 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11206 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11210 PPC::SELECT_CC_I4, dl, MVT::i32,
11211 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11214 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11215 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11218 case Intrinsic::ppc_fnmsub: {
11219 EVT VT =
Op.getOperand(1).getValueType();
11220 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11226 Op.getOperand(2),
Op.getOperand(3));
11228 case Intrinsic::ppc_convert_f128_to_ppcf128:
11229 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11230 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11231 ? RTLIB::CONVERT_PPCF128_F128
11232 : RTLIB::CONVERT_F128_PPCF128;
11233 MakeLibCallOptions CallOptions;
11234 std::pair<SDValue, SDValue>
Result =
11235 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11239 case Intrinsic::ppc_maxfe:
11240 case Intrinsic::ppc_maxfl:
11241 case Intrinsic::ppc_maxfs:
11242 case Intrinsic::ppc_minfe:
11243 case Intrinsic::ppc_minfl:
11244 case Intrinsic::ppc_minfs: {
11245 EVT VT =
Op.getValueType();
11248 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11249 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11252 if (IntrinsicID == Intrinsic::ppc_minfe ||
11253 IntrinsicID == Intrinsic::ppc_minfl ||
11254 IntrinsicID == Intrinsic::ppc_minfs)
11276 Op.getOperand(1),
Op.getOperand(2),
11287 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11295 switch (
Op.getConstantOperandVal(1)) {
11300 Bitx = PPC::sub_eq;
11306 Bitx = PPC::sub_eq;
11312 Bitx = PPC::sub_lt;
11318 Bitx = PPC::sub_lt;
11324 if (Subtarget.isISA3_1()) {
11329 CR6Reg, SubRegIdx, GlueOp),
11331 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11357 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11359 switch (
Op.getConstantOperandVal(ArgStart)) {
11360 case Intrinsic::ppc_cfence: {
11361 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11362 SDValue Val =
Op.getOperand(ArgStart + 1);
11364 if (Ty == MVT::i128) {
11369 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11372 Opcode,
DL, MVT::Other,
11394 int VectorIndex = 0;
11407 "Expecting an atomic compare-and-swap here.");
11409 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11410 EVT MemVT = AtomicNode->getMemoryVT();
11428 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11429 Ops.
push_back(AtomicNode->getOperand(i));
11441 EVT MemVT =
N->getMemoryVT();
11443 "Expect quadword atomic operations");
11445 unsigned Opc =
N->getOpcode();
11453 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11454 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11457 Ops, MemVT,
N->getMemOperand());
11464 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11474 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11484 N->getMemOperand());
11496 enum DataClassMask {
11498 DC_NEG_INF = 1 << 4,
11499 DC_POS_INF = 1 << 5,
11500 DC_NEG_ZERO = 1 << 2,
11501 DC_POS_ZERO = 1 << 3,
11502 DC_NEG_SUBNORM = 1,
11503 DC_POS_SUBNORM = 1 << 1,
11506 EVT VT =
Op.getValueType();
11508 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11509 : VT == MVT::f64 ? PPC::XSTSTDCDP
11520 return DAG.
getNOT(Dl, Rev, MVT::i1);
11527 TestOp, Dl, MVT::i32,
11529 DC_NEG_ZERO | DC_POS_ZERO |
11530 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11536 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11542 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11547 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11560 bool IsQuiet = Mask &
fcQNan;
11566 if (VT == MVT::f128) {
11570 QuietMask = 0x8000;
11571 }
else if (VT == MVT::f64) {
11583 QuietMask = 0x80000;
11584 }
else if (VT == MVT::f32) {
11586 QuietMask = 0x400000;
11602 unsigned NativeMask = 0;
11604 NativeMask |= DC_NAN;
11606 NativeMask |= DC_NEG_INF;
11608 NativeMask |= DC_POS_INF;
11610 NativeMask |= DC_NEG_ZERO;
11612 NativeMask |= DC_POS_ZERO;
11614 NativeMask |= DC_NEG_SUBNORM;
11616 NativeMask |= DC_POS_SUBNORM;
11619 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11621 TestOp, Dl, MVT::i32,
11630 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11632 uint64_t RHSC =
Op.getConstantOperandVal(1);
11635 if (
LHS.getValueType() == MVT::ppcf128) {
11651 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11652 if (isa<ConstantSDNode>(Op0) && EltSize <= 32) {
11653 int64_t
IntVal =
Op.getConstantOperandVal(0);
11654 if (IntVal >= -16 && IntVal <= 15)
11660 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11667 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11672 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
11673 return Bits.getValue(0);
11694 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11701 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11715 "Should only be called for ISD::INSERT_VECTOR_ELT");
11719 EVT VT =
Op.getValueType();
11724 if (VT == MVT::v2f64 &&
C)
11727 if (Subtarget.hasP9Vector()) {
11736 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11737 (isa<LoadSDNode>(V2))) {
11742 BitcastLoad,
Op.getOperand(2));
11743 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11747 if (Subtarget.isISA3_1()) {
11748 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11752 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11753 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11763 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11766 unsigned InsertAtElement =
C->getZExtValue();
11767 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11769 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11783 EVT VT =
Op.getValueType();
11785 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11791 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11792 "Type unsupported without MMA");
11793 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11794 "Type unsupported without paired vector support");
11799 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11801 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11811 std::reverse(Loads.
begin(), Loads.
end());
11812 std::reverse(LoadChains.
begin(), LoadChains.
end());
11830 EVT StoreVT =
Value.getValueType();
11832 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11838 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11839 "Type unsupported without MMA");
11840 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11841 "Type unsupported without paired vector support");
11844 unsigned NumVecs = 2;
11845 if (StoreVT == MVT::v512i1) {
11846 if (Subtarget.isISAFuture()) {
11847 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11849 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11852 Value2 =
SDValue(ExtNode, 1);
11857 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11860 if (Subtarget.isISAFuture()) {
11870 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11884 if (
Op.getValueType() == MVT::v4i32) {
11901 LHS, RHS, DAG, dl, MVT::v4i32);
11904 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11909 }
else if (
Op.getValueType() == MVT::v16i8) {
11915 LHS, RHS, DAG, dl, MVT::v8i16);
11920 LHS, RHS, DAG, dl, MVT::v8i16);
11928 for (
unsigned i = 0; i != 8; ++i) {
11929 if (isLittleEndian) {
11931 Ops[i*2+1] = 2*i+16;
11934 Ops[i*2+1] = 2*i+1+16;
11937 if (isLittleEndian)
11947 bool IsStrict =
Op->isStrictFPOpcode();
11948 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11949 !Subtarget.hasP9Vector())
11959 "Should only be called for ISD::FP_EXTEND");
11963 if (
Op.getValueType() != MVT::v2f64 ||
11964 Op.getOperand(0).getValueType() != MVT::v2f32)
11976 "Node should have 2 operands with second one being a constant!");
11988 int DWord =
Idx >> 1;
12011 LD->getMemoryVT(),
LD->getMemOperand());
12024 LD->getMemoryVT(),
LD->getMemOperand());
12039 for (
unsigned i = 0, ie =
U->getNumOperands(); i != ie; ++i) {
12040 if (
U->getOperand(i).getOpcode() !=
ISD::UADDO &&
12054 EVT VT =
Op.getNode()->getValueType(0);
12076 EVT VT =
Op.getNode()->getValueType(0);
12098 switch (
Op.getOpcode()) {
12118 return LowerSSUBO(
Op, DAG);
12130 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12151 return LowerSET_ROUNDING(
Op, DAG);
12158 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12159 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12171 return LowerFP_ROUND(
Op, DAG);
12184 return LowerINTRINSIC_VOID(
Op, DAG);
12186 return LowerBSWAP(
Op, DAG);
12188 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12190 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12192 return LowerIS_FPCLASS(
Op, DAG);
12200 switch (
N->getOpcode()) {
12202 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12219 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12222 assert(
N->getValueType(0) == MVT::i1 &&
12223 "Unexpected result type for CTR decrement intrinsic");
12225 N->getValueType(0));
12235 switch (
N->getConstantOperandVal(0)) {
12236 case Intrinsic::ppc_pack_longdouble:
12238 N->getOperand(2),
N->getOperand(1)));
12240 case Intrinsic::ppc_maxfe:
12241 case Intrinsic::ppc_minfe:
12242 case Intrinsic::ppc_fnmsub:
12243 case Intrinsic::ppc_convert_f128_to_ppcf128:
12253 EVT VT =
N->getValueType(0);
12255 if (VT == MVT::i64) {
12268 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12272 Results.push_back(LoweredValue);
12273 if (
N->isStrictFPOpcode())
12278 if (!
N->getValueType(0).isVector())
12333 if (isa<LoadInst>(Inst))
12344 unsigned AtomicSize,
12345 unsigned BinOpcode,
12346 unsigned CmpOpcode,
12347 unsigned CmpPred)
const {
12351 auto LoadMnemonic = PPC::LDARX;
12352 auto StoreMnemonic = PPC::STDCX;
12353 switch (AtomicSize) {
12357 LoadMnemonic = PPC::LBARX;
12358 StoreMnemonic = PPC::STBCX;
12359 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12362 LoadMnemonic = PPC::LHARX;
12363 StoreMnemonic = PPC::STHCX;
12364 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12367 LoadMnemonic = PPC::LWARX;
12368 StoreMnemonic = PPC::STWCX;
12371 LoadMnemonic = PPC::LDARX;
12372 StoreMnemonic = PPC::STDCX;
12388 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12390 F->insert(It, loopMBB);
12392 F->insert(It, loop2MBB);
12393 F->insert(It, exitMBB);
12399 Register TmpReg = (!BinOpcode) ? incr :
12401 : &PPC::GPRCRegClass);
12426 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12433 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12435 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12463 switch(
MI.getOpcode()) {
12467 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12468 &
MI.getMF()->getRegInfo());
12492 case PPC::EXTSB8_32_64:
12493 case PPC::EXTSB8_rec:
12494 case PPC::EXTSB_rec:
12497 case PPC::EXTSH8_32_64:
12498 case PPC::EXTSH8_rec:
12499 case PPC::EXTSH_rec:
12501 case PPC::EXTSWSLI:
12502 case PPC::EXTSWSLI_32_64:
12503 case PPC::EXTSWSLI_32_64_rec:
12504 case PPC::EXTSWSLI_rec:
12505 case PPC::EXTSW_32:
12506 case PPC::EXTSW_32_64:
12507 case PPC::EXTSW_32_64_rec:
12508 case PPC::EXTSW_rec:
12511 case PPC::SRAWI_rec:
12512 case PPC::SRAW_rec:
12521 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12531 bool IsSignExtended =
12534 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12536 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12537 .
addReg(
MI.getOperand(3).getReg());
12538 MI.getOperand(3).setReg(ValueReg);
12542 if (Subtarget.hasPartwordAtomics())
12550 bool is64bit = Subtarget.
isPPC64();
12552 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12563 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12565 F->insert(It, loopMBB);
12567 F->insert(It, loop2MBB);
12568 F->insert(It, exitMBB);
12574 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12619 if (ptrA != ZeroReg) {
12621 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12629 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12630 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12633 .
addImm(is8bit ? 28 : 27);
12634 if (!isLittleEndian)
12635 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12637 .
addImm(is8bit ? 24 : 16);
12639 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12644 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12654 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12658 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12663 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12667 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12670 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12682 unsigned ValueReg = SReg;
12683 unsigned CmpReg = Incr2Reg;
12684 if (CmpOpcode == PPC::CMPW) {
12686 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12690 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12692 ValueReg = ValueSReg;
12724 .
addImm(is8bit ? 24 : 16)
12745 Register DstReg =
MI.getOperand(0).getReg();
12747 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12748 Register mainDstReg =
MRI.createVirtualRegister(RC);
12749 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12752 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12753 "Invalid Pointer Size!");
12801 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12802 Register BufReg =
MI.getOperand(1).getReg();
12817 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12819 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12822 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12845 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12866 TII->get(PPC::PHI), DstReg)
12870 MI.eraseFromParent();
12884 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12885 "Invalid Pointer Size!");
12888 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12891 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12892 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12906 Register BufReg =
MI.getOperand(0).getReg();
12911 if (PVT == MVT::i64) {
12923 if (PVT == MVT::i64) {
12935 if (PVT == MVT::i64) {
12947 if (PVT == MVT::i64) {
12959 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12969 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12972 MI.eraseFromParent();
12988 "Unexpected stack alignment");
12992 unsigned StackProbeSize =
12995 StackProbeSize &= ~(StackAlign - 1);
12996 return StackProbeSize ? StackProbeSize : StackAlign;
13008 const bool isPPC64 = Subtarget.
isPPC64();
13040 MF->
insert(MBBIter, TestMBB);
13041 MF->
insert(MBBIter, BlockMBB);
13042 MF->
insert(MBBIter, TailMBB);
13047 Register DstReg =
MI.getOperand(0).getReg();
13048 Register NegSizeReg =
MI.getOperand(1).getReg();
13050 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13051 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13052 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13058 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13060 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13066 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13067 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13069 .
addDef(ActualNegSizeReg)
13071 .
add(
MI.getOperand(2))
13072 .
add(
MI.getOperand(3));
13078 .
addReg(ActualNegSizeReg);
13081 int64_t NegProbeSize = -(int64_t)ProbeSize;
13082 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
13083 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13084 if (!isInt<16>(NegProbeSize)) {
13085 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13087 .
addImm(NegProbeSize >> 16);
13091 .
addImm(NegProbeSize & 0xFFFF);
13098 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13100 .
addReg(ActualNegSizeReg)
13102 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13106 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13109 .
addReg(ActualNegSizeReg);
13118 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13119 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13144 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13146 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13147 MaxCallFrameSizeReg)
13148 .
add(
MI.getOperand(2))
13149 .
add(
MI.getOperand(3));
13150 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13152 .
addReg(MaxCallFrameSizeReg);
13161 MI.eraseFromParent();
13163 ++NumDynamicAllocaProbed;
13168 switch (
MI.getOpcode()) {
13169 case PPC::SELECT_CC_I4:
13170 case PPC::SELECT_CC_I8:
13171 case PPC::SELECT_CC_F4:
13172 case PPC::SELECT_CC_F8:
13173 case PPC::SELECT_CC_F16:
13174 case PPC::SELECT_CC_VRRC:
13175 case PPC::SELECT_CC_VSFRC:
13176 case PPC::SELECT_CC_VSSRC:
13177 case PPC::SELECT_CC_VSRC:
13178 case PPC::SELECT_CC_SPE4:
13179 case PPC::SELECT_CC_SPE:
13187 switch (
MI.getOpcode()) {
13188 case PPC::SELECT_I4:
13189 case PPC::SELECT_I8:
13190 case PPC::SELECT_F4:
13191 case PPC::SELECT_F8:
13192 case PPC::SELECT_F16:
13193 case PPC::SELECT_SPE:
13194 case PPC::SELECT_SPE4:
13195 case PPC::SELECT_VRRC:
13196 case PPC::SELECT_VSFRC:
13197 case PPC::SELECT_VSSRC:
13198 case PPC::SELECT_VSRC:
13208 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13209 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13211 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13224 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13225 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13227 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13228 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13242 if (Subtarget.hasISEL() &&
13243 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13244 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13245 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13247 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13248 MI.getOpcode() == PPC::SELECT_CC_I8)
13249 Cond.push_back(
MI.getOperand(4));
13252 Cond.push_back(
MI.getOperand(1));
13255 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13256 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13272 F->insert(It, copy0MBB);
13273 F->insert(It, sinkMBB);
13277 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13292 .
addReg(
MI.getOperand(1).getReg())
13295 unsigned SelectPred =
MI.getOperand(4).getImm();
13298 .
addReg(
MI.getOperand(1).getReg())
13315 .
addReg(
MI.getOperand(3).getReg())
13317 .
addReg(
MI.getOperand(2).getReg())
13319 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13335 F->insert(It, readMBB);
13336 F->insert(It, sinkMBB);
13357 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13367 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13369 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13371 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13373 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13376 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13378 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13380 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13382 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13385 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13387 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13389 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13391 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13394 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13396 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13398 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13400 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13403 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13405 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13407 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13409 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13412 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13414 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13416 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13418 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13421 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13423 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13425 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13427 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13430 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13432 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13434 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13436 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13439 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13441 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13443 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13445 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13448 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13450 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13452 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13454 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13457 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13459 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13461 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13463 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13465 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13466 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13467 (Subtarget.hasPartwordAtomics() &&
13468 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13469 (Subtarget.hasPartwordAtomics() &&
13470 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13471 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13473 auto LoadMnemonic = PPC::LDARX;
13474 auto StoreMnemonic = PPC::STDCX;
13475 switch (
MI.getOpcode()) {
13478 case PPC::ATOMIC_CMP_SWAP_I8:
13479 LoadMnemonic = PPC::LBARX;
13480 StoreMnemonic = PPC::STBCX;
13481 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13483 case PPC::ATOMIC_CMP_SWAP_I16:
13484 LoadMnemonic = PPC::LHARX;
13485 StoreMnemonic = PPC::STHCX;
13486 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13488 case PPC::ATOMIC_CMP_SWAP_I32:
13489 LoadMnemonic = PPC::LWARX;
13490 StoreMnemonic = PPC::STWCX;
13492 case PPC::ATOMIC_CMP_SWAP_I64:
13493 LoadMnemonic = PPC::LDARX;
13494 StoreMnemonic = PPC::STDCX;
13502 Register oldval =
MI.getOperand(3).getReg();
13503 Register newval =
MI.getOperand(4).getReg();
13509 F->insert(It, loop1MBB);
13510 F->insert(It, loop2MBB);
13511 F->insert(It, exitMBB);
13532 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13558 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13559 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13563 bool is64bit = Subtarget.
isPPC64();
13565 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13570 Register oldval =
MI.getOperand(3).getReg();
13571 Register newval =
MI.getOperand(4).getReg();
13577 F->insert(It, loop1MBB);
13578 F->insert(It, loop2MBB);
13579 F->insert(It, exitMBB);
13586 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13605 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13637 if (ptrA != ZeroReg) {
13639 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13648 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13649 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13652 .
addImm(is8bit ? 28 : 27);
13653 if (!isLittleEndian)
13654 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13656 .
addImm(is8bit ? 24 : 16);
13658 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13663 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13668 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13671 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13678 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13682 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13685 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13688 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13693 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13710 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13734 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13759 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13767 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13768 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13769 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13770 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13771 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13772 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13775 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13776 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13780 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13784 .
addReg(
MI.getOperand(1).getReg())
13787 MI.getOperand(0).getReg())
13788 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13789 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13795 MI.getOperand(0).getReg())
13797 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13799 unsigned Imm =
MI.getOperand(1).getImm();
13802 MI.getOperand(0).getReg())
13804 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13806 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13809 if (
MRI.use_empty(OldFPSCRReg))
13810 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13812 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13823 unsigned Mode =
MI.getOperand(1).getImm();
13824 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13828 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13831 }
else if (
MI.getOpcode() == PPC::SETRND) {
13839 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13840 if (Subtarget.hasDirectMove()) {
13841 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13845 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13848 if (RC == &PPC::F8RCRegClass) {
13851 "Unsupported RegClass.");
13853 StoreOp = PPC::STFD;
13858 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13859 "Unsupported RegClass.");
13892 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13895 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13909 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13917 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13918 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13924 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13931 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13940 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13944 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13945 if (
MRI.use_empty(OldFPSCRReg))
13946 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13948 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13951 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13957 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13958 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13960 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13967 .
addUse(Src, 0, PPC::sub_gp8_x1);
13970 .
addUse(Src, 0, PPC::sub_gp8_x0);
13971 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13972 MI.getOpcode() == PPC::STQX_PSEUDO) {
13978 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13984 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13985 :
TII->get(PPC::STQ))
13993 MI.eraseFromParent();
14006 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14009 return RefinementSteps;
14015 EVT VT =
Op.getValueType();
14018 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14042PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14045 EVT VT =
Op.getValueType();
14046 if (VT != MVT::f64 &&
14047 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14054 int Enabled,
int &RefinementSteps,
14055 bool &UseOneConstNR,
14056 bool Reciprocal)
const {
14058 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14059 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14060 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14061 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14067 UseOneConstNR = !Subtarget.needsTwoConstNR();
14075 int &RefinementSteps)
const {
14077 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14078 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14079 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14080 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14088unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
14126 unsigned Bytes,
int Dist,
14136 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
14137 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
14140 if (FS != BFS || FS != (
int)Bytes)
return false;
14144 SDValue Base1 = Loc, Base2 = BaseLoc;
14145 int64_t Offset1 = 0, Offset2 = 0;
14148 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14158 if (isGA1 && isGA2 && GV1 == GV2)
14159 return Offset1 == (Offset2 + Dist*Bytes);
14166 unsigned Bytes,
int Dist,
14169 EVT VT = LS->getMemoryVT();
14170 SDValue Loc = LS->getBasePtr();
14176 switch (
N->getConstantOperandVal(1)) {
14177 default:
return false;
14178 case Intrinsic::ppc_altivec_lvx:
14179 case Intrinsic::ppc_altivec_lvxl:
14180 case Intrinsic::ppc_vsx_lxvw4x:
14181 case Intrinsic::ppc_vsx_lxvw4x_be:
14184 case Intrinsic::ppc_vsx_lxvd2x:
14185 case Intrinsic::ppc_vsx_lxvd2x_be:
14188 case Intrinsic::ppc_altivec_lvebx:
14191 case Intrinsic::ppc_altivec_lvehx:
14194 case Intrinsic::ppc_altivec_lvewx:
14204 switch (
N->getConstantOperandVal(1)) {
14205 default:
return false;
14206 case Intrinsic::ppc_altivec_stvx:
14207 case Intrinsic::ppc_altivec_stvxl:
14208 case Intrinsic::ppc_vsx_stxvw4x:
14211 case Intrinsic::ppc_vsx_stxvd2x:
14214 case Intrinsic::ppc_vsx_stxvw4x_be:
14217 case Intrinsic::ppc_vsx_stxvd2x_be:
14220 case Intrinsic::ppc_altivec_stvebx:
14223 case Intrinsic::ppc_altivec_stvehx:
14226 case Intrinsic::ppc_altivec_stvewx:
14243 SDValue Chain = LD->getChain();
14244 EVT VT = LD->getMemoryVT();
14253 while (!Queue.empty()) {
14254 SDNode *ChainNext = Queue.pop_back_val();
14255 if (!Visited.
insert(ChainNext).second)
14258 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
14262 if (!Visited.
count(ChainLD->getChain().getNode()))
14263 Queue.push_back(ChainLD->getChain().getNode());
14265 for (
const SDUse &O : ChainNext->
ops())
14266 if (!Visited.
count(O.getNode()))
14267 Queue.push_back(O.getNode());
14269 LoadRoots.
insert(ChainNext);
14280 for (
SDNode *
I : LoadRoots) {
14281 Queue.push_back(
I);
14283 while (!Queue.empty()) {
14284 SDNode *LoadRoot = Queue.pop_back_val();
14285 if (!Visited.
insert(LoadRoot).second)
14288 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
14293 if (((isa<MemSDNode>(U) &&
14294 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
14297 Queue.push_back(U);
14330 auto Final = Shifted;
14341 DAGCombinerInfo &DCI)
const {
14349 if (!DCI.isAfterLegalizeDAG())
14354 for (
const SDNode *U :
N->users())
14359 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14363 if (OpSize <
Size) {
14381 DAGCombinerInfo &DCI)
const {
14385 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14396 N->getValueType(0) != MVT::i1)
14399 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14400 N->getOperand(0).getValueType() != MVT::i64)
14408 cast<CondCodeSDNode>(
N->getOperand(
14410 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14421 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14444 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14445 N->getOperand(0).getOpcode() !=
ISD::OR &&
14446 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14456 N->getOperand(1).getOpcode() !=
ISD::AND &&
14457 N->getOperand(1).getOpcode() !=
ISD::OR &&
14458 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14471 for (
unsigned i = 0; i < 2; ++i) {
14475 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14476 isa<ConstantSDNode>(
N->getOperand(i)))
14487 while (!BinOps.
empty()) {
14495 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14529 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14530 if (isa<ConstantSDNode>(Inputs[i]))
14553 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14575 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14578 if (isa<ConstantSDNode>(Inputs[i]))
14584 std::list<HandleSDNode> PromOpHandles;
14585 for (
auto &PromOp : PromOps)
14586 PromOpHandles.emplace_back(PromOp);
14593 while (!PromOpHandles.empty()) {
14595 PromOpHandles.pop_back();
14601 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14604 PromOpHandles.emplace_front(PromOp);
14609 if (isa<ConstantSDNode>(RepValue))
14618 default:
C = 0;
break;
14623 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14631 PromOpHandles.emplace_front(PromOp);
14638 for (
unsigned i = 0; i < 2; ++i)
14639 if (isa<ConstantSDNode>(Ops[
C+i]))
14648 return N->getOperand(0);
14656 DAGCombinerInfo &DCI)
const {
14674 if (
N->getValueType(0) != MVT::i32 &&
14675 N->getValueType(0) != MVT::i64)
14678 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14679 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14682 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14683 N->getOperand(0).getOpcode() !=
ISD::OR &&
14684 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14695 while (!BinOps.
empty()) {
14703 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14734 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14735 if (isa<ConstantSDNode>(Inputs[i]))
14746 SelectTruncOp[0].
insert(std::make_pair(
User,
14750 SelectTruncOp[0].
insert(std::make_pair(
User,
14753 SelectTruncOp[1].
insert(std::make_pair(
User,
14759 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14768 SelectTruncOp[0].
insert(std::make_pair(
User,
14772 SelectTruncOp[0].
insert(std::make_pair(
User,
14775 SelectTruncOp[1].
insert(std::make_pair(
User,
14781 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14782 bool ReallyNeedsExt =
false;
14786 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14787 if (isa<ConstantSDNode>(Inputs[i]))
14791 Inputs[i].getOperand(0).getValueSizeInBits();
14792 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14797 OpBits-PromBits))) ||
14800 (OpBits-(PromBits-1)))) {
14801 ReallyNeedsExt =
true;
14809 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14813 if (isa<ConstantSDNode>(Inputs[i]))
14816 SDValue InSrc = Inputs[i].getOperand(0);
14830 std::list<HandleSDNode> PromOpHandles;
14831 for (
auto &PromOp : PromOps)
14832 PromOpHandles.emplace_back(PromOp);
14838 while (!PromOpHandles.empty()) {
14840 PromOpHandles.pop_back();
14844 default:
C = 0;
break;
14849 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14857 PromOpHandles.emplace_front(PromOp);
14867 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14869 PromOpHandles.emplace_front(PromOp);
14878 for (
unsigned i = 0; i < 2; ++i) {
14879 if (!isa<ConstantSDNode>(Ops[
C+i]))
14896 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14897 if (SI0 != SelectTruncOp[0].
end())
14899 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14900 if (SI1 != SelectTruncOp[1].
end())
14909 if (!ReallyNeedsExt)
14910 return N->getOperand(0);
14917 N->getValueSizeInBits(0), PromBits),
14918 dl,
N->getValueType(0)));
14921 "Invalid extension type");
14924 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14932 DAGCombinerInfo &DCI)
const {
14934 "Should be called with a SETCC node");
14952 EVT VT =
N->getValueType(0);
14953 EVT OpVT =
LHS.getValueType();
14959 return DAGCombineTruncBoolExt(
N, DCI);
14964 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14966 Op.getValueType() == MVT::f64;
14978combineElementTruncationToVectorTruncation(
SDNode *
N,
14979 DAGCombinerInfo &DCI)
const {
14981 "Should be called with a BUILD_VECTOR node");
14986 SDValue FirstInput =
N->getOperand(0);
14988 "The input operand must be an fp-to-int conversion.");
14997 bool IsSplat =
true;
15002 EVT TargetVT =
N->getValueType(0);
15003 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15004 SDValue NextOp =
N->getOperand(i);
15008 if (NextConversion != FirstConversion)
15016 if (
N->getOperand(i) != FirstInput)
15027 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15028 SDValue In =
N->getOperand(i).getOperand(0);
15051 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15053 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15066 "Should be called with a BUILD_VECTOR node");
15071 if (!
N->getValueType(0).getVectorElementType().isByteSized())
15074 bool InputsAreConsecutiveLoads =
true;
15075 bool InputsAreReverseConsecutive =
true;
15076 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
15077 SDValue FirstInput =
N->getOperand(0);
15078 bool IsRoundOfExtLoad =
false;
15083 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
15088 N->getNumOperands() == 1)
15091 if (!IsRoundOfExtLoad)
15092 FirstLoad = cast<LoadSDNode>(FirstInput);
15096 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
15098 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
15101 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
15107 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
15108 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
15109 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
15118 InputsAreConsecutiveLoads =
false;
15120 InputsAreReverseConsecutive =
false;
15123 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15128 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15129 "The loads cannot be both consecutive and reverse consecutive.");
15133 if (InputsAreConsecutiveLoads) {
15134 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
15138 ReturnSDVal = WideLoad;
15139 }
else if (InputsAreReverseConsecutive) {
15141 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
15146 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
15150 DAG.
getUNDEF(
N->getValueType(0)), Ops);
15154 for (
auto *LD : InputLoads)
15156 return ReturnSDVal;
15173 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15175 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
15177 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
15178 CorrectElems = CorrectElems >> 8;
15179 Elems = Elems >> 8;
15186 EVT VT =
N->getValueType(0);
15224 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
15244 if (Input && Input != Extract.
getOperand(0))
15250 Elems = Elems << 8;
15259 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15260 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15267 int TgtElemArrayIdx;
15269 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15270 if (InputSize + OutputSize == 40)
15271 TgtElemArrayIdx = 0;
15272 else if (InputSize + OutputSize == 72)
15273 TgtElemArrayIdx = 1;
15274 else if (InputSize + OutputSize == 48)
15275 TgtElemArrayIdx = 2;
15276 else if (InputSize + OutputSize == 80)
15277 TgtElemArrayIdx = 3;
15278 else if (InputSize + OutputSize == 96)
15279 TgtElemArrayIdx = 4;
15283 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15285 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15286 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15287 if (Elems != CorrectElems) {
15303 if (
N->getValueType(0) != MVT::v1i128)
15306 SDValue Operand =
N->getOperand(0);
15312 auto *LD = cast<LoadSDNode>(Operand);
15313 EVT MemoryType = LD->getMemoryVT();
15317 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15318 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15321 if (!ValidLDType ||
15327 LD->getChain(), LD->getBasePtr(),
15331 DAG.
getVTList(MVT::v1i128, MVT::Other),
15332 LoadOps, MemoryType, LD->getMemOperand());
15336 DAGCombinerInfo &DCI)
const {
15338 "Should be called with a BUILD_VECTOR node");
15343 if (!Subtarget.hasVSX())
15349 SDValue FirstInput =
N->getOperand(0);
15351 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15366 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15375 if (Subtarget.isISA3_1()) {
15381 if (
N->getValueType(0) != MVT::v2f64)
15392 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15396 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15403 if (!Ext1Op || !Ext2Op)
15412 if (FirstElem == 0 && SecondElem == 1)
15414 else if (FirstElem == 2 && SecondElem == 3)
15422 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15427 DAGCombinerInfo &DCI)
const {
15430 "Need an int -> FP conversion node here");
15441 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15443 if (!
Op.getOperand(0).getValueType().isSimple())
15445 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15446 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15449 SDValue FirstOperand(
Op.getOperand(0));
15450 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15451 (FirstOperand.getValueType() == MVT::i8 ||
15452 FirstOperand.getValueType() == MVT::i16);
15453 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15455 bool DstDouble =
Op.getValueType() == MVT::f64;
15456 unsigned ConvOp =
Signed ?
15462 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15471 SDValue ExtOps[] = { Ld, WidthConst };
15473 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15475 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15483 if (
Op.getOperand(0).getValueType() == MVT::i32)
15487 "UINT_TO_FP is supported only with FPCVT");
15491 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15496 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15503 Subtarget.hasFPCVT()) ||
15505 SDValue Src =
Op.getOperand(0).getOperand(0);
15506 if (Src.getValueType() == MVT::f32) {
15508 DCI.AddToWorklist(Src.getNode());
15509 }
else if (Src.getValueType() != MVT::f64) {
15521 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15524 DCI.AddToWorklist(
FP.getNode());
15548 switch (
N->getOpcode()) {
15553 Chain = LD->getChain();
15554 Base = LD->getBasePtr();
15555 MMO = LD->getMemOperand();
15574 MVT VecTy =
N->getValueType(0).getSimpleVT();
15582 Chain = Load.getValue(1);
15588 if (VecTy != MVT::v2f64) {
15615 switch (
N->getOpcode()) {
15620 Chain = ST->getChain();
15621 Base = ST->getBasePtr();
15622 MMO = ST->getMemOperand();
15642 SDValue Src =
N->getOperand(SrcOpnd);
15643 MVT VecTy = Src.getValueType().getSimpleVT();
15646 if (VecTy != MVT::v2f64) {
15652 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15658 StoreOps, VecTy, MMO);
15665 DAGCombinerInfo &DCI)
const {
15668 unsigned Opcode =
N->getOperand(1).getOpcode();
15670 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15674 &&
"Not a FP_TO_INT Instruction!");
15676 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15677 EVT Op1VT =
N->getOperand(1).getValueType();
15680 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15684 bool ValidTypeForStoreFltAsInt =
15685 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15686 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15689 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15692 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15693 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15700 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15706 cast<StoreSDNode>(
N)->getMemoryVT(),
15707 cast<StoreSDNode>(
N)->getMemOperand());
15715 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15716 for (
int i = 1, e = Mask.size(); i < e; i++) {
15717 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15719 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15721 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15733 FirstOp =
Op.getOperand(i);
15740 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15750 Op =
Op.getOperand(0);
15766 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
15767 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
15769 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
15771 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
15772 for (
int I = 0, E = ShuffV.
size();
I < E; ++
I) {
15773 int Idx = ShuffV[
I];
15774 if (
Idx >= LHSFirstElt &&
Idx <= LHSLastElt)
15775 ShuffV[
I] += LHSEltFixup;
15776 else if (
Idx >= RHSFirstElt &&
Idx <= RHSLastElt)
15777 ShuffV[
I] += RHSEltFixup;
15788 SDLoc dl(OrigSToV);
15791 "Expecting a SCALAR_TO_VECTOR here");
15804 "Cannot produce a permuted scalar_to_vector for one element vector");
15806 unsigned ResultInElt = NumElts / 2;
15808 NewMask[ResultInElt] =
Idx->getZExtValue();
15817 int HalfVec,
int LHSLastElementDefined,
15818 int RHSLastElementDefined) {
15819 for (
int Index : ShuffV) {
15823 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
15824 (Index > LHSLastElementDefined))
15827 if ((RHSLastElementDefined >= 0) &&
15828 (Index > HalfVec + RHSLastElementDefined))
15835 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
15836 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
15852 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
15853 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
15856 if (SToVPermuted.
getValueType() != VecShuffOperandType)
15857 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
15858 return SToVPermuted;
15878 int NumElts =
LHS.getValueType().getVectorNumElements();
15888 if (!Subtarget.hasDirectMove())
15898 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15907 if (SToVLHS || SToVRHS) {
15910 int ShuffleNumElts = ShuffV.
size();
15911 int HalfVec = ShuffleNumElts / 2;
15917 unsigned LHSNumValidElts = HalfVec;
15918 unsigned RHSNumValidElts = HalfVec;
15923 int LHSFirstElt = 0;
15924 int RHSFirstElt = ShuffleNumElts;
15925 int LHSLastElt = -1;
15926 int RHSLastElt = -1;
15934 int LHSScalarSize = 0;
15935 int RHSScalarSize = 0;
15938 if (!IsLittleEndian && LHSScalarSize >= 64)
15943 if (!IsLittleEndian && RHSScalarSize >= 64)
15946 if (LHSScalarSize != 0)
15948 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
15949 LHSLastElt, LHS, SToVLHS, DAG, Subtarget);
15950 if (RHSScalarSize != 0)
15952 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
15953 RHSLastElt, RHS, SToVRHS, DAG, Subtarget);
15964 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
15965 LHSNumValidElts, RHSNumValidElts, Subtarget);
15970 if (!isa<ShuffleVectorSDNode>(Res))
15972 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15991 if (IsLittleEndian) {
15994 if (Mask[0] < NumElts)
15995 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15999 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16004 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
16008 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
16013 if (Mask[0] < NumElts)
16014 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
16018 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
16023 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
16027 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
16034 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
16037 if (IsLittleEndian)
16046 DAGCombinerInfo &DCI)
const {
16048 "Not a reverse memop pattern!");
16053 auto I =
Mask.rbegin();
16054 auto E =
Mask.rend();
16056 for (;
I != E; ++
I) {
16073 if (!Subtarget.hasP9Vector())
16076 if(!IsElementReverse(SVN))
16084 if (
Use.getResNo() == 0 &&
16115 if (IntrinsicID == Intrinsic::ppc_stdcx)
16117 else if (IntrinsicID == Intrinsic::ppc_stwcx)
16119 else if (IntrinsicID == Intrinsic::ppc_sthcx)
16121 else if (IntrinsicID == Intrinsic::ppc_stbcx)
16132 switch (
N->getOpcode()) {
16135 return combineADD(
N, DCI);
16144 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
16154 if (!isUInt<32>(Imm))
16161 return combineSHL(
N, DCI);
16163 return combineSRA(
N, DCI);
16165 return combineSRL(
N, DCI);
16167 return combineMUL(
N, DCI);
16170 return combineFMALike(
N, DCI);
16173 return N->getOperand(0);
16177 return N->getOperand(0);
16183 return N->getOperand(0);
16189 return DAGCombineExtBoolTrunc(
N, DCI);
16191 return combineTRUNCATE(
N, DCI);
16193 if (
SDValue CSCC = combineSetCC(
N, DCI))
16197 return DAGCombineTruncBoolExt(
N, DCI);
16200 return combineFPToIntToFP(
N, DCI);
16203 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
16204 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
16206 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
16209 EVT Op1VT =
N->getOperand(1).getValueType();
16210 unsigned Opcode =
N->getOperand(1).getOpcode();
16214 SDValue Val = combineStoreFPToInt(
N, DCI);
16221 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
16227 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
16228 N->getOperand(1).getNode()->hasOneUse() &&
16229 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
16230 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
16234 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
16238 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
16245 if (Op1VT.
bitsGT(mVT)) {
16250 if (Op1VT == MVT::i64)
16255 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
16259 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
16260 cast<StoreSDNode>(
N)->getMemOperand());
16266 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
16268 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
16278 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
16287 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
16288 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
16295 EVT VT = LD->getValueType(0);
16302 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16303 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16314 auto ReplaceTwoFloatLoad = [&]() {
16315 if (VT != MVT::i64)
16330 if (!LD->hasNUsesOfValue(2, 0))
16333 auto UI = LD->user_begin();
16334 while (UI.getUse().getResNo() != 0) ++UI;
16336 while (UI.getUse().getResNo() != 0) ++UI;
16337 SDNode *RightShift = *UI;
16345 if (RightShift->getOpcode() !=
ISD::SRL ||
16346 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
16347 RightShift->getConstantOperandVal(1) != 32 ||
16348 !RightShift->hasOneUse())
16351 SDNode *Trunc2 = *RightShift->user_begin();
16361 Bitcast->getValueType(0) != MVT::f32)
16373 SDValue BasePtr = LD->getBasePtr();
16374 if (LD->isIndexed()) {
16376 "Non-pre-inc AM on PPC?");
16384 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16385 LD->getPointerInfo(), LD->getAlign(),
16386 MMOFlags, LD->getAAInfo());
16392 LD->getPointerInfo().getWithOffset(4),
16395 if (LD->isIndexed()) {
16409 if (ReplaceTwoFloatLoad())
16412 EVT MemVT = LD->getMemoryVT();
16415 if (LD->isUnindexed() && VT.
isVector() &&
16418 !Subtarget.hasP8Vector() &&
16419 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16420 VT == MVT::v4f32))) &&
16421 LD->getAlign() < ABIAlignment) {
16423 SDValue Chain = LD->getChain();
16452 MVT PermCntlTy, PermTy, LDTy;
16453 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16454 : Intrinsic::ppc_altivec_lvsl;
16455 IntrLD = Intrinsic::ppc_altivec_lvx;
16456 IntrPerm = Intrinsic::ppc_altivec_vperm;
16457 PermCntlTy = MVT::v16i8;
16458 PermTy = MVT::v4i32;
16477 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16481 BaseLoadOps, LDTy, BaseMMO);
16490 int IncValue = IncOffset;
16507 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16511 ExtraLoadOps, LDTy, ExtraMMO);
16522 if (isLittleEndian)
16524 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16527 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16530 Perm = Subtarget.hasAltivec()
16546 unsigned IID =
N->getConstantOperandVal(0);
16548 : Intrinsic::ppc_altivec_lvsl);
16549 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16556 .
zext(
Add.getScalarValueSizeInBits()))) {
16557 SDNode *BasePtr =
Add->getOperand(0).getNode();
16558 for (
SDNode *U : BasePtr->users()) {
16560 U->getConstantOperandVal(0) == IID) {
16570 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16571 SDNode *BasePtr =
Add->getOperand(0).getNode();
16572 for (
SDNode *U : BasePtr->users()) {
16574 isa<ConstantSDNode>(U->getOperand(1)) &&
16575 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16581 V->getConstantOperandVal(0) == IID) {
16593 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16594 IID == Intrinsic::ppc_altivec_vmaxsh ||
16595 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16611 V2.getOperand(1) == V1) {
16626 switch (
N->getConstantOperandVal(1)) {
16629 case Intrinsic::ppc_altivec_vsum4sbs:
16630 case Intrinsic::ppc_altivec_vsum4shs:
16631 case Intrinsic::ppc_altivec_vsum4ubs: {
16637 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16638 APInt APSplatBits, APSplatUndef;
16639 unsigned SplatBitSize;
16642 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16645 if (BVNIsConstantSplat && APSplatBits == 0)
16650 case Intrinsic::ppc_vsx_lxvw4x:
16651 case Intrinsic::ppc_vsx_lxvd2x:
16663 switch (
N->getConstantOperandVal(1)) {
16666 case Intrinsic::ppc_vsx_stxvw4x:
16667 case Intrinsic::ppc_vsx_stxvd2x:
16676 bool Is64BitBswapOn64BitTgt =
16677 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16679 N->getOperand(0).hasOneUse();
16680 if (IsSingleUseNormalLd &&
16681 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16682 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16693 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16694 MVT::i64 : MVT::i32, MVT::Other),
16695 Ops, LD->getMemoryVT(), LD->getMemOperand());
16699 if (
N->getValueType(0) == MVT::i16)
16716 !IsSingleUseNormalLd)
16718 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16721 if (!LD->isSimple())
16723 SDValue BasePtr = LD->getBasePtr();
16725 LD->getPointerInfo(), LD->getAlign());
16730 LD->getMemOperand(), 4, 4);
16740 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16749 if (!
N->getOperand(0).hasOneUse() &&
16750 !
N->getOperand(1).hasOneUse() &&
16751 !
N->getOperand(2).hasOneUse()) {
16754 SDNode *VCMPrecNode =
nullptr;
16756 SDNode *LHSN =
N->getOperand(0).getNode();
16762 VCMPrecNode =
User;
16774 SDNode *FlagUser =
nullptr;
16776 FlagUser ==
nullptr; ++UI) {
16777 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16790 return SDValue(VCMPrecNode, 0);
16812 auto RHSAPInt =
RHS->getAsAPIntVal();
16813 if (!RHSAPInt.isIntN(64))
16816 unsigned Val = RHSAPInt.getZExtValue();
16817 auto isImpossibleCompare = [&]() {
16820 if (Val != 0 && Val != 1) {
16822 return N->getOperand(0);
16825 N->getOperand(0),
N->getOperand(4));
16830 unsigned StoreWidth = 0;
16833 if (
SDValue Impossible = isImpossibleCompare())
16847 auto *MemNode = cast<MemSDNode>(
LHS);
16850 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16851 MemNode->getMemoryVT(), MemNode->getMemOperand());
16855 if (
N->getOperand(0) ==
LHS.getValue(1))
16856 InChain =
LHS.getOperand(0);
16868 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16874 assert(isDot &&
"Can't compare against a vector result!");
16876 if (
SDValue Impossible = isImpossibleCompare())
16879 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16886 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16891 switch (
LHS.getConstantOperandVal(1)) {
16910 N->getOperand(4), CompNode.
getValue(1));
16915 return DAGCombineBuildVector(
N, DCI);
16926 EVT VT =
N->getValueType(0);
16927 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16929 if ((VT != MVT::i32 && VT != MVT::i64) ||
16937 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16957 const APInt &DemandedElts,
16959 unsigned Depth)
const {
16961 switch (
Op.getOpcode()) {
16965 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16966 Known.
Zero = 0xFFFF0000;
16970 switch (
Op.getConstantOperandVal(0)) {
16972 case Intrinsic::ppc_altivec_vcmpbfp_p:
16973 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16974 case Intrinsic::ppc_altivec_vcmpequb_p:
16975 case Intrinsic::ppc_altivec_vcmpequh_p:
16976 case Intrinsic::ppc_altivec_vcmpequw_p:
16977 case Intrinsic::ppc_altivec_vcmpequd_p:
16978 case Intrinsic::ppc_altivec_vcmpequq_p:
16979 case Intrinsic::ppc_altivec_vcmpgefp_p:
16980 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16981 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16982 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16983 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16984 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16985 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16986 case Intrinsic::ppc_altivec_vcmpgtub_p:
16987 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16988 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16989 case Intrinsic::ppc_altivec_vcmpgtud_p:
16990 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16997 switch (
Op.getConstantOperandVal(1)) {
17000 case Intrinsic::ppc_load2r:
17002 Known.
Zero = 0xFFFF0000;
17033 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
17042 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
17044 LoopSize +=
TII->getInstSizeInBytes(J);
17049 if (LoopSize > 16 && LoopSize <= 32)
17063 if (Constraint.
size() == 1) {
17064 switch (Constraint[0]) {
17082 }
else if (Constraint ==
"wc") {
17084 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
17085 Constraint ==
"wf" || Constraint ==
"ws" ||
17086 Constraint ==
"wi" || Constraint ==
"ww") {
17099 Value *CallOperandVal =
info.CallOperandVal;
17102 if (!CallOperandVal)
17109 else if ((
StringRef(constraint) ==
"wa" ||
17121 switch (*constraint) {
17151std::pair<unsigned, const TargetRegisterClass *>
17155 if (Constraint.
size() == 1) {
17157 switch (Constraint[0]) {
17159 if (VT == MVT::i64 && Subtarget.
isPPC64())
17160 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
17161 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
17163 if (VT == MVT::i64 && Subtarget.
isPPC64())
17164 return std::make_pair(0U, &PPC::G8RCRegClass);
17165 return std::make_pair(0U, &PPC::GPRCRegClass);
17171 if (Subtarget.hasSPE()) {
17172 if (VT == MVT::f32 || VT == MVT::i32)
17173 return std::make_pair(0U, &PPC::GPRCRegClass);
17174 if (VT == MVT::f64 || VT == MVT::i64)
17175 return std::make_pair(0U, &PPC::SPERCRegClass);
17177 if (VT == MVT::f32 || VT == MVT::i32)
17178 return std::make_pair(0U, &PPC::F4RCRegClass);
17179 if (VT == MVT::f64 || VT == MVT::i64)
17180 return std::make_pair(0U, &PPC::F8RCRegClass);
17184 if (Subtarget.hasAltivec() && VT.
isVector())
17185 return std::make_pair(0U, &PPC::VRRCRegClass);
17186 else if (Subtarget.hasVSX())
17188 return std::make_pair(0U, &PPC::VFRCRegClass);
17191 return std::make_pair(0U, &PPC::CRRCRegClass);
17193 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
17195 return std::make_pair(0U, &PPC::CRBITRCRegClass);
17196 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
17197 Constraint ==
"wf" || Constraint ==
"wi") &&
17198 Subtarget.hasVSX()) {
17202 return std::make_pair(0U, &PPC::VSRCRegClass);
17203 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17204 return std::make_pair(0U, &PPC::VSSRCRegClass);
17205 return std::make_pair(0U, &PPC::VSFRCRegClass);
17206 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
17207 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17208 return std::make_pair(0U, &PPC::VSSRCRegClass);
17210 return std::make_pair(0U, &PPC::VSFRCRegClass);
17211 }
else if (Constraint ==
"lr") {
17212 if (VT == MVT::i64)
17213 return std::make_pair(0U, &PPC::LR8RCRegClass);
17215 return std::make_pair(0U, &PPC::LRRCRegClass);
17220 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
17224 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
17225 int VSNum = atoi(Constraint.
data() + 3);
17226 assert(VSNum >= 0 && VSNum <= 63 &&
17227 "Attempted to access a vsr out of range");
17229 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
17230 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
17235 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
17236 int RegNum = atoi(Constraint.
data() + 2);
17237 if (RegNum > 31 || RegNum < 0)
17239 if (VT == MVT::f32 || VT == MVT::i32)
17240 return Subtarget.hasSPE()
17241 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
17242 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
17243 if (VT == MVT::f64 || VT == MVT::i64)
17244 return Subtarget.hasSPE()
17245 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
17246 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
17250 std::pair<unsigned, const TargetRegisterClass *> R =
17259 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
17260 PPC::GPRCRegClass.contains(R.first))
17261 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
17262 PPC::sub_32, &PPC::G8RCRegClass),
17263 &PPC::G8RCRegClass);
17266 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
17267 R.first = PPC::CR0;
17268 R.second = &PPC::CRRCRegClass;
17272 if (Subtarget.
isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
17273 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
17274 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
17275 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
17276 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
17277 "default AIX AltiVec ABI and cannot be used\n";
17287 std::vector<SDValue> &Ops,
17292 if (Constraint.
size() > 1)
17295 char Letter = Constraint[0];
17310 EVT TCVT = MVT::i64;
17315 if (isInt<16>(
Value))
17319 if (isShiftedUInt<16, 16>(
Value))
17323 if (isShiftedInt<16, 16>(
Value))
17327 if (isUInt<16>(
Value))
17343 if (isInt<16>(-
Value))
17351 if (Result.getNode()) {
17352 Ops.push_back(Result);
17363 if (
I.getNumOperands() <= 1)
17365 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17367 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17368 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17369 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17372 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17400 switch (AM.
Scale) {
17431 unsigned Depth =
Op.getConstantOperandVal(0);
17455 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17463 unsigned Depth =
Op.getConstantOperandVal(0);
17470 bool isPPC64 = PtrVT == MVT::i64;
17476 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17478 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17488#define GET_REGISTER_MATCHER
17489#include "PPCGenAsmMatcher.inc"
17493 bool IsPPC64 = Subtarget.
isPPC64();
17506 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
17512 Reg = Reg.id() - PPC::R0 + PPC::X0;
17534 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17552 unsigned Intrinsic)
const {
17553 switch (Intrinsic) {
17554 case Intrinsic::ppc_atomicrmw_xchg_i128:
17555 case Intrinsic::ppc_atomicrmw_add_i128:
17556 case Intrinsic::ppc_atomicrmw_sub_i128:
17557 case Intrinsic::ppc_atomicrmw_nand_i128:
17558 case Intrinsic::ppc_atomicrmw_and_i128:
17559 case Intrinsic::ppc_atomicrmw_or_i128:
17560 case Intrinsic::ppc_atomicrmw_xor_i128:
17561 case Intrinsic::ppc_cmpxchg_i128:
17563 Info.memVT = MVT::i128;
17564 Info.ptrVal =
I.getArgOperand(0);
17570 case Intrinsic::ppc_atomic_load_i128:
17572 Info.memVT = MVT::i128;
17573 Info.ptrVal =
I.getArgOperand(0);
17578 case Intrinsic::ppc_atomic_store_i128:
17580 Info.memVT = MVT::i128;
17581 Info.ptrVal =
I.getArgOperand(2);
17586 case Intrinsic::ppc_altivec_lvx:
17587 case Intrinsic::ppc_altivec_lvxl:
17588 case Intrinsic::ppc_altivec_lvebx:
17589 case Intrinsic::ppc_altivec_lvehx:
17590 case Intrinsic::ppc_altivec_lvewx:
17591 case Intrinsic::ppc_vsx_lxvd2x:
17592 case Intrinsic::ppc_vsx_lxvw4x:
17593 case Intrinsic::ppc_vsx_lxvd2x_be:
17594 case Intrinsic::ppc_vsx_lxvw4x_be:
17595 case Intrinsic::ppc_vsx_lxvl:
17596 case Intrinsic::ppc_vsx_lxvll: {
17598 switch (Intrinsic) {
17599 case Intrinsic::ppc_altivec_lvebx:
17602 case Intrinsic::ppc_altivec_lvehx:
17605 case Intrinsic::ppc_altivec_lvewx:
17608 case Intrinsic::ppc_vsx_lxvd2x:
17609 case Intrinsic::ppc_vsx_lxvd2x_be:
17619 Info.ptrVal =
I.getArgOperand(0);
17626 case Intrinsic::ppc_altivec_stvx:
17627 case Intrinsic::ppc_altivec_stvxl:
17628 case Intrinsic::ppc_altivec_stvebx:
17629 case Intrinsic::ppc_altivec_stvehx:
17630 case Intrinsic::ppc_altivec_stvewx:
17631 case Intrinsic::ppc_vsx_stxvd2x:
17632 case Intrinsic::ppc_vsx_stxvw4x:
17633 case Intrinsic::ppc_vsx_stxvd2x_be:
17634 case Intrinsic::ppc_vsx_stxvw4x_be:
17635 case Intrinsic::ppc_vsx_stxvl:
17636 case Intrinsic::ppc_vsx_stxvll: {
17638 switch (Intrinsic) {
17639 case Intrinsic::ppc_altivec_stvebx:
17642 case Intrinsic::ppc_altivec_stvehx:
17645 case Intrinsic::ppc_altivec_stvewx:
17648 case Intrinsic::ppc_vsx_stxvd2x:
17649 case Intrinsic::ppc_vsx_stxvd2x_be:
17659 Info.ptrVal =
I.getArgOperand(1);
17666 case Intrinsic::ppc_stdcx:
17667 case Intrinsic::ppc_stwcx:
17668 case Intrinsic::ppc_sthcx:
17669 case Intrinsic::ppc_stbcx: {
17671 auto Alignment =
Align(8);
17672 switch (Intrinsic) {
17673 case Intrinsic::ppc_stdcx:
17676 case Intrinsic::ppc_stwcx:
17678 Alignment =
Align(4);
17680 case Intrinsic::ppc_sthcx:
17682 Alignment =
Align(2);
17684 case Intrinsic::ppc_stbcx:
17686 Alignment =
Align(1);
17691 Info.ptrVal =
I.getArgOperand(0);
17693 Info.align = Alignment;
17711 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17712 if (
Op.isMemset() && Subtarget.hasVSX()) {
17717 if (TailSize > 2 && TailSize <= 4) {
17722 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17741 return !(BitSize == 0 || BitSize > 64);
17749 return NumBits1 == 64 && NumBits2 == 32;
17757 return NumBits1 == 64 && NumBits2 == 32;
17763 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17764 EVT MemVT = LD->getMemoryVT();
17765 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17766 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17782 "invalid fpext types");
17784 if (DestVT == MVT::f128)
17790 return isInt<16>(Imm) || isUInt<16>(Imm);
17794 return isInt<16>(Imm) || isUInt<16>(Imm);
17799 unsigned *
Fast)
const {
17813 !Subtarget.allowsUnalignedFPAccess())
17817 if (Subtarget.hasVSX()) {
17818 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17819 VT != MVT::v4f32 && VT != MVT::v4i32)
17826 if (VT == MVT::ppcf128)
17840 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17841 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17849 int64_t Imm = ConstNode->getSExtValue();
17850 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17852 if (isInt<16>(Imm))
17877 return Subtarget.hasP9Vector();
17885 if (!
I->hasOneUse())
17889 assert(
User &&
"A single use instruction with no uses.");
17891 switch (
I->getOpcode()) {
17892 case Instruction::FMul: {
17894 if (
User->getOpcode() != Instruction::FSub &&
17895 User->getOpcode() != Instruction::FAdd)
17908 case Instruction::Load: {
17921 if (
User->getOpcode() != Instruction::Store)
17941 static const MCPhysReg ScratchRegs[] = {
17942 PPC::X12, PPC::LR8, PPC::CTR8, 0
17945 return ScratchRegs;
17949 const Constant *PersonalityFn)
const {
17950 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17954 const Constant *PersonalityFn)
const {
17955 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17960 EVT VT ,
unsigned DefinedValues)
const {
17961 if (VT == MVT::v2i64)
17962 return Subtarget.hasDirectMove();
17964 if (Subtarget.hasVSX())
17998 bool LegalOps,
bool OptForSize,
18000 unsigned Depth)
const {
18004 unsigned Opc =
Op.getOpcode();
18005 EVT VT =
Op.getValueType();
18030 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
18034 N0Cost,
Depth + 1);
18038 N1Cost,
Depth + 1);
18040 if (NegN0 && N0Cost <= N1Cost) {
18041 Cost = std::min(N0Cost, N2Cost);
18042 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
18043 }
else if (NegN1) {
18044 Cost = std::min(N1Cost, N2Cost);
18045 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
18064 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.
isTargetLinux())
18088 bool ForCodeSize)
const {
18089 if (!VT.
isSimple() || !Subtarget.hasVSX())
18099 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
18104 APSInt IntResult(16,
false);
18109 if (IsExact && IntResult <= 15 && IntResult >= -16)
18111 return Imm.isZero();
18114 return Imm.isPosZero();
18126 unsigned Opcode =
N->getOpcode();
18127 unsigned TargetOpcode;
18146 if (Mask->getZExtValue() == OpSizeInBits - 1)
18152SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18158 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
18161 N->getValueType(0) != MVT::i64)
18176 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
18182SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18189SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18208 auto isZextOfCompareWithConstant = [](
SDValue Op) {
18210 Op.getValueType() != MVT::i64)
18214 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
18215 Cmp.getOperand(0).getValueType() != MVT::i64)
18218 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
18219 int64_t NegConstant = 0 -
Constant->getSExtValue();
18222 return isInt<16>(NegConstant);
18228 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
18229 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
18232 if (LHSHasPattern && !RHSHasPattern)
18234 else if (!LHSHasPattern && !RHSHasPattern)
18240 SDValue Z = Cmp.getOperand(0);
18241 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
18242 int64_t NegConstant = 0 -
Constant->getSExtValue();
18244 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
18255 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18270 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18307 if (!GSDN || !ConstNode)
18314 if (!isInt<34>(NewOffset))
18327SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18347 DAGCombinerInfo &DCI)
const {
18349 if (Subtarget.useCRBits()) {
18351 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
18352 return CRTruncValue;
18359 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
18362 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18372 EltToExtract = EltToExtract ? 0 : 1;
18382 return DCI.DAG.getNode(
18384 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18389SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18393 if (!ConstOpOrElement)
18401 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18425 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18429 EVT VT =
N->getValueType(0);
18436 if ((MulAmtAbs - 1).isPowerOf2()) {
18440 if (!IsProfitable(IsNeg,
true, VT))
18453 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18457 if (!IsProfitable(IsNeg,
false, VT))
18478 DAGCombinerInfo &DCI)
const {
18483 EVT VT =
N->getValueType(0);
18486 unsigned Opc =
N->getOpcode();
18488 bool LegalOps = !DCI.isBeforeLegalizeOps();
18496 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18512bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18529 if (!Callee ||
Callee->isVarArg())
18542bool PPCTargetLowering::
18543isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18546 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18548 if (CI->getBitWidth() > 64)
18550 int64_t ConstVal = CI->getZExtValue();
18551 return isUInt<16>(ConstVal) ||
18552 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18561PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18567 if ((Flags & FlagSet) == FlagSet)
18570 if ((Flags & FlagSet) == FlagSet)
18573 if ((Flags & FlagSet) == FlagSet)
18576 if ((Flags & FlagSet) == FlagSet)
18597 if ((FrameIndexAlign % 4) != 0)
18598 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18599 if ((FrameIndexAlign % 16) != 0)
18600 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18604 if ((FrameIndexAlign % 4) == 0)
18606 if ((FrameIndexAlign % 16) == 0)
18619 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18620 if ((Imm & 0x3) == 0)
18622 if ((Imm & 0xf) == 0)
18628 const APInt &ConstImm = CN->getAPIntValue();
18647 const APInt &ConstImm = CN->getAPIntValue();
18657 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18669 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18670 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18671 isValidPCRelNode<JumpTableSDNode>(
N) ||
18672 isValidPCRelNode<BlockAddressSDNode>(
N));
18677unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18682 if (!Subtarget.hasP9Vector())
18687 if (Subtarget.hasPrefixInstrs())
18690 if (Subtarget.hasSPE())
18699 unsigned ParentOp = Parent->
getOpcode();
18703 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18704 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18715 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18716 if (LSB->isIndexed())
18721 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18722 assert(MN &&
"Parent should be a MemSDNode!");
18727 "Not expecting scalar integers larger than 16 bytes!");
18730 else if (
Size == 32)
18737 else if (
Size == 256) {
18738 assert(Subtarget.pairedVectorMemops() &&
18739 "256-bit vectors are only available when paired vector memops is "
18747 else if (MemVT == MVT::f128 || MemVT.
isVector())
18757 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18778 FlagSet &= ~PPC::MOF_NoExt;
18783 bool IsNonP1034BitConst =
18787 IsNonP1034BitConst)
18800 int16_t ForceXFormImm = 0;
18803 Disp =
N.getOperand(0);
18804 Base =
N.getOperand(1);
18815 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18816 Disp =
N.getOperand(0);
18817 Base =
N.getOperand(1);
18831 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18837 if (PartVT == MVT::f64 &&
18838 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18847SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18851 EVT RetVT =
Op.getValueType();
18859 EVT ArgVT =
N.getValueType();
18864 Entry.IsZExt = !Entry.IsSExt;
18865 Args.push_back(Entry);
18873 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18879 .setTailCall(isTailCall)
18886SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18887 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18889 if (
Op.getValueType() == MVT::f32)
18890 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18892 if (
Op.getValueType() == MVT::f64)
18893 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18898bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18900 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18904bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18905 return Op.getNode()->getFlags().hasApproximateFuncs();
18908bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18912SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18913 const char *LibCallFloatName,
18914 const char *LibCallDoubleNameFinite,
18915 const char *LibCallFloatNameFinite,
18918 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18921 if (!isLowringToMASSFiniteSafe(
Op))
18922 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18925 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18926 LibCallDoubleNameFinite,
Op, DAG);
18930 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18931 "__xl_powf_finite",
Op, DAG);
18935 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18936 "__xl_sinf_finite",
Op, DAG);
18940 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18941 "__xl_cosf_finite",
Op, DAG);
18945 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18946 "__xl_logf_finite",
Op, DAG);
18950 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18951 "__xl_log10f_finite",
Op, DAG);
18955 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18956 "__xl_expf_finite",
Op, DAG);
18963 if (!isa<FrameIndexSDNode>(
N))
18981 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18993 "Must be using PC-Relative calls when a valid PC-Relative node is "
19023 Disp =
N.getOperand(1).getOperand(0);
19028 Base =
N.getOperand(0);
19035 auto *CN = cast<ConstantSDNode>(
N);
19036 EVT CNType = CN->getValueType(0);
19037 uint64_t CNImm = CN->getZExtValue();
19048 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
19050 int32_t
Addr = (int32_t)CNImm;
19055 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
19071 unsigned Opcode =
N.getOpcode();
19079 Base =
N.getOperand(0);
19098 Base = FI ?
N :
N.getOperand(1);
19110 bool IsVarArg)
const {
19120 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
19156 return Intrinsic::ppc_atomicrmw_xchg_i128;
19158 return Intrinsic::ppc_atomicrmw_add_i128;
19160 return Intrinsic::ppc_atomicrmw_sub_i128;
19162 return Intrinsic::ppc_atomicrmw_and_i128;
19164 return Intrinsic::ppc_atomicrmw_or_i128;
19166 return Intrinsic::ppc_atomicrmw_xor_i128;
19168 return Intrinsic::ppc_atomicrmw_nand_i128;
19185 {AlignedAddr, IncrLo, IncrHi});
19191 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19212 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
19219 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
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)
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.
static int getEstimateRefinementSteps(EVT VT, const LoongArchSubtarget &Subtarget)
static bool isConstantOrUndef(const SDValue Op)
static bool isSplat(Value *V)
Return true if V is a splat of a value (which is used when multiplying a matrix with a scalar).
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
cl::opt< bool > ANDIGlueBug("expose-ppc-andi-glue-bug", cl::desc("expose the ANDI glue bug on PPC"), cl::Hidden)
static SDValue getCanonicalConstSplat(uint64_t Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, const SDLoc &dl)
getCanonicalConstSplat - Build a canonical splat immediate of Val with an element size of SplatSize.
static bool IsSelectCC(MachineInstr &MI)
static const TargetRegisterClass * getRegClassForSVT(MVT::SimpleValueType SVT, bool IsPPC64, bool HasP8Vector, bool HasVSX)
static bool isGPRShadowAligned(MCPhysReg Reg, Align RequiredAlign)
static bool needStackSlotPassParameters(const PPCSubtarget &Subtarget, const SmallVectorImpl< ISD::OutputArg > &Outs)
static bool isAlternatingShuffMask(const ArrayRef< int > &Mask, int NumElts)
static 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 bool haveEfficientBuildVectorPattern(BuildVectorSDNode *V, bool HasDirectMove, bool HasP8Vector)
Do we have an efficient pattern in a .td file for this node?
static SDValue getSToVPermuted(SDValue OrigSToV, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static bool CC_AIX(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &S)
static void setUsesTOCBasePtr(MachineFunction &MF)
static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG, const SDLoc &dl, const PPCSubtarget &Subtarget)
static unsigned EnsureStackAlignment(const PPCFrameLowering *Lowering, unsigned NumBytes)
EnsureStackAlignment - Round stack frame size up from NumBytes to ensure minimum alignment required f...
static SDValue stripModuloOnShift(const TargetLowering &TLI, SDNode *N, SelectionDAG &DAG)
static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth)
static bool hasSameArgumentList(const Function *CallerFn, const CallBase &CB)
static bool isFPExtLoad(SDValue Op)
static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op, SelectionDAG &DAG, const SDLoc &dl, EVT DestVT=MVT::Other)
BuildIntrinsicOp - Return a unary operator intrinsic node with the specified intrinsic ID.
static bool isConsecutiveLSLoc(SDValue Loc, EVT VT, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static void StoreTailCallArgumentsToStackSlot(SelectionDAG &DAG, SDValue Chain, const SmallVectorImpl< TailCallArgumentInfo > &TailCallArgs, SmallVectorImpl< SDValue > &MemOpChains, const SDLoc &dl)
StoreTailCallArgumentsToStackSlot - Stores arguments to their stack slot.
static const char AIXSSPCanaryWordName[]
static cl::opt< bool > UseAbsoluteJumpTables("ppc-use-absolute-jumptables", cl::desc("use absolute jump tables on ppc"), cl::Hidden)
static void setXFormForUnalignedFI(SDValue N, unsigned Flags, PPC::AddrMode &Mode)
static void getMaxByValAlign(Type *Ty, Align &MaxAlign, Align MaxMaxAlign)
getMaxByValAlign - Helper for getByValTypeAlignment to determine the desired ByVal argument alignment...
static bool isConsecutiveLS(SDNode *N, LSBaseSDNode *Base, unsigned Bytes, int Dist, SelectionDAG &DAG)
static bool isVMerge(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned LHSStart, unsigned RHSStart)
isVMerge - Common function, used to match vmrg* shuffles.
static void getLabelAccessInfo(bool IsPIC, const PPCSubtarget &Subtarget, unsigned &HiOpFlags, unsigned &LoOpFlags, const GlobalValue *GV=nullptr)
Return true if we should reference labels using a PICBase, set the HiOpFlags and LoOpFlags to the tar...
cl::opt< bool > DisableAutoPairedVecSt("disable-auto-paired-vec-st", cl::desc("disable automatically generated 32byte paired vector stores"), cl::init(true), cl::Hidden)
static void buildCallOperands(SmallVectorImpl< SDValue > &Ops, PPCTargetLowering::CallFlags CFlags, const SDLoc &dl, SelectionDAG &DAG, SmallVector< std::pair< unsigned, SDValue >, 8 > &RegsToPass, SDValue Glue, SDValue Chain, SDValue &Callee, int SPDiff, const PPCSubtarget &Subtarget)
static cl::opt< bool > DisableInnermostLoopAlign32("disable-ppc-innermost-loop-align32", cl::desc("don't always align innermost loop to 32 bytes on ppc"), cl::Hidden)
static bool usePartialVectorLoads(SDNode *N, const PPCSubtarget &ST)
Returns true if we should use a direct load into vector instruction (such as lxsd or lfd),...
static SDValue getDataClassTest(SDValue Op, FPClassTest Mask, const SDLoc &Dl, SelectionDAG &DAG, const PPCSubtarget &Subtarget)
static 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)
static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, bool &isDot, const PPCSubtarget &Subtarget)
getVectorCompareInfo - Given an intrinsic, return false if it is not a vector comparison.
static unsigned invertFMAOpcode(unsigned Opc)
static const SDValue * getNormalLoadInput(const SDValue &Op, bool &IsPermuted)
static cl::opt< unsigned > PPCMinimumJumpTableEntries("ppc-min-jump-table-entries", cl::init(64), cl::Hidden, cl::desc("Set minimum number of entries to use a jump table on PPC"))
static bool isValidSplatLoad(const PPCSubtarget &Subtarget, const SDValue &Op, unsigned &Opcode)
static SDValue convertIntToFP(SDValue Op, SDValue Src, SelectionDAG &DAG, const PPCSubtarget &Subtarget, SDValue Chain=SDValue())
static 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 Register SPReg
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI optimize exec mask operations pre RA
static const MCExpr * MaskShift(const MCExpr *Val, uint32_t Mask, uint32_t Shift, MCContext &Ctx)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
bool isFixed(unsigned ValNo) const
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
APInt zext(unsigned width) const
Zero extend to a new width.
uint64_t getZExtValue() const
Get zero extended value.
void setBit(unsigned BitPosition)
Set the given bit to 1 whose position is given as "bitPosition".
APInt abs() const
Get the absolute value.
bool isNegative() const
Determine sign of this APInt.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool getBoolValue() const
Convert APInt to a boolean value.
double bitsToDouble() const
Converts APInt bits to a double.
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
An arbitrary precision integer that knows its signedness.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
Value * getNewValOperand()
an instruction that atomically reads a memory location, combines it with another value,...
BinOp
This enumeration lists the possible modifications atomicrmw can make.
@ 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.
StringRef getValueAsString() const
Return the attribute's value as a string.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
int64_t getOffset() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
static BranchProbability getOne()
static BranchProbability getZero()
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign 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.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
bool isLittleEndian() const
Layout endianness...
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
uint64_t getFnAttributeAsParsedInteger(StringRef Kind, uint64_t Default=0) const
For a string attribute Kind, parse attribute as an integer.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
AttributeList getAttributes() const
Return the attribute list for this Function.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Type * getReturnType() const
Returns the type of the ret val.
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
int64_t getOffset() const
unsigned getTargetFlags() const
const GlobalValue * getGlobal() const
const GlobalObject * getAliaseeObject() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
void setThreadLocalMode(ThreadLocalMode Val)
bool hasHiddenVisibility() const
StringRef getSection() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Type * getValueType() const
bool hasProtectedVisibility() const
Common base class shared among various IRBuilders.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
BasicBlock * GetInsertBlock() const
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.
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 * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
bool hasAtomicLoad() const LLVM_READONLY
Return true if this atomic instruction loads from memory.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Base class for LoadSDNode and StoreSDNode.
An instruction for reading from memory.
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
TypeSize getValue() const
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
Wrapper class representing physical registers. Should be passed by value.
MCSymbolXCOFF * getQualNameSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
@ INVALID_SIMPLE_VALUE_TYPE
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()
void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
void setCallFrameSize(unsigned N)
Set the call frame size on entry to this basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setHasTailCall(bool V=true)
void setReturnAddressIsTaken(bool s)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
@ EK_LabelDifference32
EK_LabelDifference32 - Each entry is the address of the block minus the address of the jump table.
A description of a memory reference used in the backend.
LocationSize getSize() const
Return the size in bytes of the memory reference.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
Flags getFlags() const
Return the raw flags of the source value,.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Register getLiveInVirtReg(MCRegister PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in virtual r...
An SDNode that represents everything that will be needed to construct a MachineInstr.
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
This is an abstract virtual class for memory operations.
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
const SDValue & getChain() const
EVT getMemoryVT() const
Return the type of the in-memory value.
A Module instance is used to store all the information related to an LLVM module.
uint64_t getReturnSaveOffset() const
getReturnSaveOffset - Return the previous frame offset to save the return address.
uint64_t getFramePointerSaveOffset() const
getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.
unsigned getLinkageSize() const
getLinkageSize - Return the size of the PowerPC ABI linkage area.
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
void setVarArgsNumFPR(unsigned Num)
void setReturnAddrSaveIndex(int idx)
bool isAIXFuncUseTLSIEForLD() const
int getReturnAddrSaveIndex() const
unsigned getVarArgsNumFPR() const
void setAIXFuncUseTLSIEForLD()
int getFramePointerSaveIndex() const
void setVarArgsNumGPR(unsigned Num)
void appendParameterType(ParamType Type)
int getVarArgsFrameIndex() const
void setLRStoreRequired()
bool isAIXFuncTLSModelOptInitDone() const
void setTailCallSPDelta(int size)
void setAIXFuncTLSModelOptInitDone()
bool isLRStoreRequired() const
void setMinReservedArea(unsigned size)
unsigned getVarArgsNumGPR() const
unsigned getMinReservedArea() const
void setVarArgsStackOffset(int Offset)
void setVarArgsFrameIndex(int Index)
void addLiveInAttr(Register VReg, ISD::ArgFlagsTy Flags)
This function associates attributes for each live-in virtual register.
int getVarArgsStackOffset() const
void setFramePointerSaveIndex(int Idx)
static bool hasPCRelFlag(unsigned TF)
bool is32BitELFABI() const
unsigned descriptorTOCAnchorOffset() const
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...
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.
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
bool SelectAddressRegRegOnly(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressRegRegOnly - Given the specified addressed, force it to be represented as an indexed [r+...
bool useSoftFloat() const override
SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const override
Returns relocation base for the given PIC jumptable.
void insertSSPDeclarations(Module &M) const override
Inserts necessary declarations for SSP (stack protection) purpose.
Value * emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder, AtomicCmpXchgInst *CI, Value *AlignedAddr, Value *CmpVal, Value *NewVal, Value *Mask, AtomicOrdering Ord) const override
Perform a masked cmpxchg using a target-specific intrinsic.
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const override
Examine constraint string and operand type and determine a weight value.
bool enableAggressiveFMAFusion(EVT VT) const override
Return true if target always benefits from combining into FMA for a given value type.
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
bool decomposeMulByConstant(LLVMContext &Context, EVT VT, SDValue C) const override
Return true if it is profitable to transform an integer multiplication-by-constant into simpler opera...
unsigned getJumpTableEncoding() const override
Return the entry encoding for a jump table in the current function.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
isLegalAddressingMode - Return true if the addressing mode represented by AM is legal for this target...
bool preferIncOfAddToSubOfNot(EVT VT) const override
These two forms are equivalent: sub y, (xor x, -1) add (add x, 1), y The variant with two add's is IR...
bool shouldConvertConstantLoadToIntImm(const APInt &Imm, Type *Ty) const override
Returns true if it is beneficial to convert a load of a constant to just the constant itself.
const MCPhysReg * getScratchRegisters(CallingConv::ID CC) const override
Returns a 0 terminated array of registers that can be safely used as scratch registers.
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const override
getPreIndexedAddressParts - returns true by value, base pointer and offset pointer and addressing mod...
bool isProfitableToHoist(Instruction *I) const override
isProfitableToHoist - Check if it is profitable to hoist instruction I to its dominator block.
bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override
Returns true if the target can instruction select the specified FP immediate natively.
ConstraintType getConstraintType(StringRef Constraint) const override
getConstraintType - Given a constraint, return the type of constraint it is for this target.
const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const override
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
bool shallExtractConstSplatVectorElementToStore(Type *VectorTy, unsigned ElemSizeInBits, unsigned &Index) const override
Return true if the target shall perform extract vector element and store given that the vector is kno...
EVT getOptimalMemOpType(const MemOp &Op, const AttributeList &FuncAttributes) const override
It returns EVT::Other if the type should be determined using generic target-independent logic.
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
SDValue expandVSXStoreForLE(SDNode *N, DAGCombinerInfo &DCI) const
void CollectTargetIntrinsicOperands(const CallInst &I, SmallVectorImpl< SDValue > &Ops, SelectionDAG &DAG) const override
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...
Value * getSDagStackGuard(const Module &M) const override
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
bool SelectAddressPCRel(SDValue N, SDValue &Base) const
SelectAddressPCRel - Represent the specified address as pc relative to be represented as [pc+imm].
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, EVT VT) const override
getSetCCResultType - Return the ISD::SETCC ValueType
bool SelectAddressEVXRegReg(SDValue N, SDValue &Base, SDValue &Index, SelectionDAG &DAG) const
SelectAddressEVXRegReg - Given the specified addressed, check to see if it can be more efficiently re...
bool isLegalICmpImmediate(int64_t Imm) const override
isLegalICmpImmediate - Return true if the specified immediate is legal icmp immediate,...
bool isAccessedAsGotIndirect(SDValue N) const
Align getPrefLoopAlignment(MachineLoop *ML) const override
Return the preferred loop alignment.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo) const override
createFastISel - This method returns a target-specific FastISel object, or null if the target does no...
bool shouldInlineQuadwordAtomics() const
Instruction * emitLeadingFence(IRBuilderBase &Builder, Instruction *Inst, AtomicOrdering Ord) const override
Inserts in the IR a target-specific intrinsic specifying a fence.
bool isLegalAddImmediate(int64_t Imm) const override
isLegalAddImmediate - Return true if the specified immediate is legal add immediate,...
Common code between 32-bit and 64-bit PowerPC targets.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
ArrayRef< SDUse > ops() const
void dump() const
Dump this node, for debugging.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool hasOneUse() const
Return true if there is exactly one use of this node.
iterator_range< use_iterator > uses()
SDNodeFlags getFlags() const
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
const SDValue & getOperand(unsigned Num) const
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
iterator_range< user_iterator > users()
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
op_iterator op_end() const
op_iterator op_begin() const
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const SDValue & getOperand(unsigned i) const
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
unsigned getOpcode() const
unsigned getNumOperands() const
static SectionKind getMetadata()
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getStackArgumentTokenFactor(SDValue Chain)
Compute a TokenFactor to force all the incoming stack arguments to be loaded from the stack.
const TargetSubtargetInfo & getSubtarget() const
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
MachineSDNode * getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT)
These are used for target selectors to create a new node with specified return type(s),...
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain)
If an existing load has uses of its chain, create a token factor node with that chain and the new mem...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT, bool isTarget=false)
Create a ConstantFPSDNode wrapping a constant value.
SDValue getRegister(Register Reg, EVT VT)
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
Align getEVTAlign(EVT MemoryVT) const
Compute the default alignment value for the given type.
void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge)
Set NoMergeSiteInfo to be associated with Node if NoMerge is true.
SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT)
Create a bitwise NOT operation as (XOR Val, -1).
const TargetLowering & getTargetLoweringInfo() const
static constexpr unsigned MaxRecursionDepth
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getUNDEF(EVT VT)
Return an UNDEF node. UNDEF does not have a useful SDLoc.
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef< SDValue > Ops)
Return an ISD::BUILD_VECTOR node.
bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts, unsigned Depth=0) const
Test whether V has a splatted value for all the demanded elements.
SDValue getBitcast(EVT VT, SDValue V)
Return a bitcast using the SDLoc of the value operand, and casting to the provided type.
SDValue 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)
SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl< SDValue > &Vals)
Creates a new TokenFactor containing Vals.
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base, unsigned Bytes, int Dist) const
Return true if loads are next to each other and can be merged.
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, EVT SVT, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
SDValue getMDNode(const MDNode *MD)
Return an MDNodeSDNode which holds an MDNode.
void ReplaceAllUsesWith(SDValue From, SDValue To)
Modify anything using 'From' to use 'To' instead.
SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV)
Returns an ISD::VECTOR_SHUFFLE node semantically equivalent to the shuffle node in input but with swa...
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue 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 getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either sign-extending or trunca...
SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT)
Convert Op, which must be of integer type, to the integer type VT, by using an extension appropriate ...
SDValue getExternalSymbol(const char *Sym, EVT VT)
const TargetMachine & getTarget() const
SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either any-extending or truncat...
SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True, SDValue False, ISD::CondCode Cond)
Helper function to make it easier to build SelectCC's if you just have an ISD::CondCode instead of an...
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
unsigned ComputeNumSignBits(SDValue Op, unsigned Depth=0) const
Return the number of times the sign bit of the register is replicated into the other bits.
SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT)
Create a true or false constant of type VT using the target's BooleanContent for type OpVT.
SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, unsigned TargetFlags=0)
bool isBaseWithConstantOffset(SDValue Op) const
Return true if the specified operand is an ISD::ADD with a ConstantSDNode on the right-hand side,...
SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
void ReplaceAllUsesOfValueWith(SDValue From, SDValue To)
Replace any uses of From with To, leaving uses of other values produced by From.getNode() alone.
MachineFunction & getMachineFunction() const
SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op)
Return a splat ISD::BUILD_VECTOR node, consisting of Op splatted to all elements.
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
SDValue getRegisterMask(const uint32_t *RegMask)
SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT)
Convert Op, which must be of integer type, to the integer type VT, by either zero-extending or trunca...
SDValue getCondCode(ISD::CondCode Cond)
bool MaskedValueIsZero(SDValue Op, const APInt &Mask, unsigned Depth=0) const
Return true if 'Op & Mask' is known to be zero.
SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset)
Create an add instruction with appropriate flags when used for addressing some offset of an object.
LLVMContext * getContext() const
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef< SDValue > Ops, EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags Flags=MachineMemOperand::MOLoad|MachineMemOperand::MOStore, LocationSize Size=0, const AAMDNodes &AAInfo=AAMDNodes())
Creates a MemIntrinsicNode that may produce a result and takes a list of operands.
SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getMCSymbol(MCSymbol *Sym, EVT VT)
SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment)
Create a stack temporary based on the size in bytes and the alignment.
SDNode * UpdateNodeOperands(SDNode *N, SDValue Op)
Mutate the specified node in-place to have the specified operands.
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
std::pair< SDValue, SDValue > SplitScalar(const SDValue &N, const SDLoc &DL, const EVT &LoVT, const EVT &HiVT)
Split the scalar node with EXTRACT_ELEMENT using the provided VTs and return the low/high part.
SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2, ArrayRef< int > Mask)
Return an ISD::VECTOR_SHUFFLE node.
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
int getMaskElt(unsigned Idx) const
ArrayRef< int > getMask() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getValue() const
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
Information about stack frame layout on the target.
unsigned getStackAlignment() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
Provides information about what library functions are available for the current target.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
bool PredictableSelectIsExpensive
Tells the code generator that select is more expensive than a branch if the branch is usually predict...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
virtual bool shouldExpandBuildVectorWithShuffles(EVT, unsigned DefinedValues) const
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
MachineBasicBlock * emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const
Replace/modify any TargetFrameIndex operands with a targte-dependent sequence of memory operands that...
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
void setMinStackArgumentAlignment(Align Alignment)
Set the minimum stack alignment of an argument.
virtual MVT getVectorIdxTy(const DataLayout &DL) const
Returns the type to be used for the index operand of: ISD::INSERT_VECTOR_ELT, ISD::EXTRACT_VECTOR_ELT...
const TargetMachine & getTargetMachine() const
unsigned MaxLoadsPerMemcmp
Specify maximum number of load instructions per memcmp call.
virtual bool isZExtFree(Type *FromTy, Type *ToTy) const
Return true if any actual instruction that defines a value of type FromTy implicitly zero-extends the...
virtual Value * getSDagStackGuard(const Module &M) const
Return the variable that's previously inserted by insertSSPDeclarations, if any, otherwise return nul...
void setIndexedLoadAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed load does or does not work with the specified type and indicate w...
void setPrefLoopAlignment(Align Alignment)
Set the target's preferred loop alignment.
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Sched::Preference getSchedulingPreference() const
Return target scheduling preference.
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
bool isOperationCustom(unsigned Op, EVT VT) const
Return true if the operation uses custom lowering, regardless of whether the type is legal or not.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
bool hasBigEndianPartOrdering(EVT VT, const DataLayout &DL) const
When splitting a value of the specified type into parts, does the Lo or Hi part come first?...
EVT getShiftAmountTy(EVT LHSTy, const DataLayout &DL) const
Returns the type for the shift amount of a shift opcode.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
virtual Align getPrefLoopAlignment(MachineLoop *ML=nullptr) const
Return the preferred loop alignment.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
void setIndexedStoreAction(ArrayRef< unsigned > IdxModes, MVT VT, LegalizeAction Action)
Indicate that the specified indexed store does or does not work with the specified type and indicate ...
virtual bool isJumpTableRelative() const
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setLibcallName(RTLIB::Libcall Call, const char *Name)
Rename the default libcall routine name for the specified libcall.
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
bool isOperationLegal(unsigned Op, EVT VT) const
Return true if the specified operation is legal on this target.
virtual AtomicExpansionKind shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const
Returns how the given atomic cmpxchg should be expanded by the IR-level AtomicExpand pass.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setTruncStoreAction(MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified truncating store does not work with the specified type and indicate what ...
@ ZeroOrOneBooleanContent
@ ZeroOrNegativeOneBooleanContent
bool isOperationLegalOrCustom(unsigned Op, EVT VT, bool LegalOnly=false) const
Return true if the specified operation is legal on this target or can be made legal with custom lower...
unsigned MaxLoadsPerMemcmpOptSize
Likewise for functions with the OptSize attribute.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void AddPromotedToType(unsigned Opc, MVT OrigVT, MVT DestVT)
If Opc/OrigVT is specified as being promoted, the promotion code defaults to trying a larger integer/...
AtomicExpansionKind
Enum that specifies what an atomic load/AtomicRMWInst is expanded to, if at all.
void setCondCodeAction(ArrayRef< ISD::CondCode > CCs, MVT VT, LegalizeAction Action)
Indicate that the specified condition code is or isn't supported on the target and indicate what to d...
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
virtual AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *RMW) const
Returns how the IR-level AtomicExpand pass should expand the given AtomicRMW, if at all.
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned GatherAllAliasesMaxDepth
Depth that GatherAllAliases should continue looking for chain dependencies when trying to find a more...
NegatibleCost
Enum that specifies when a float negation is beneficial.
virtual bool shouldSignExtendTypeInLibCall(Type *Ty, bool IsSigned) const
Returns true if arguments should be sign-extended in lib calls.
std::vector< ArgListEntry > ArgListTy
void setHasMultipleConditionRegisters(bool hasManyRegs=true)
Tells the code generator that the target has multiple (allocatable) condition registers that can be u...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
virtual void insertSSPDeclarations(Module &M) const
Inserts necessary declarations for SSP (stack protection) purpose.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual MCSymbol * getFunctionEntryPointSymbol(const GlobalValue *Func, const TargetMachine &TM) const
If supported, return the function entry point symbol.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const MCExpr * getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const
This returns the relocation base for the given PIC jumptable, the same as getPICJumpTableRelocBase,...
SDValue lowerCmpEqZeroToCtlzSrl(SDValue Op, SelectionDAG &DAG) const
void softenSetCCOperands(SelectionDAG &DAG, EVT VT, SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode, const SDLoc &DL, const SDValue OldLHS, const SDValue OldRHS) const
Soften the operands of a comparison.
std::pair< SDValue, SDValue > makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT, ArrayRef< SDValue > Ops, MakeLibCallOptions CallOptions, const SDLoc &dl, SDValue Chain=SDValue()) const
Returns a pair of (return value, chain).
SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, unsigned Depth=0) const
This is the helper function to return the newly negated expression only when the cost is cheaper.
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const
Lower TLS global address SDNode for target independent emulated TLS model.
std::pair< SDValue, SDValue > LowerCallTo(CallLoweringInfo &CLI) const
This function lowers an abstract call to a function into an actual call.
bool isPositionIndependent() const
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps, bool OptForSize, NegatibleCost &Cost, unsigned Depth=0) const
Return the newly negated expression if the cost is not expensive and set the cost in Cost to indicate...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual SDValue getSqrtInputTest(SDValue Operand, SelectionDAG &DAG, const DenormalMode &Mode) const
Return a target-dependent comparison result if the input operand is suitable for use with a square ro...
virtual SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const
Returns relocation base for the given PIC jumptable.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
bool verifyReturnAddressArgumentIsConstant(SDValue Op, SelectionDAG &DAG) const
bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node, SDValue &Chain) const
Check whether a given call node is in tail position within its function.
virtual SDValue getSqrtResultForDenormInput(SDValue Operand, SelectionDAG &DAG) const
Return a target-dependent result if the input operand is not suitable for use with a square root esti...
virtual 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.
bool isVectorTy() const
True if this is an instance of VectorType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ FP128TyID
128-bit floating point type (112-bit significand)
static Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isFunctionTy() const
True if this is an instance of FunctionType.
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
A Use represents the edge between a Value definition and its users.
User * getUser() const
Returns the User that contains this Use.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char 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.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ FMA
FMA - Perform a * b + c with no intermediate rounding step.
@ INTRINSIC_VOID
OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...) This node represents a target intrin...
@ SINT_TO_FP
[SU]INT_TO_FP - These operators convert integers (whose interpreted sign depends on the first letter)...
@ CONCAT_VECTORS
CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of vector type with the same length ...
@ FADD
Simple binary floating point operators.
@ ABS
ABS - Determine the unsigned absolute value of a signed integer value of the same bitwidth.
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
@ FP16_TO_FP
FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions and truncation for half-preci...
@ BITCAST
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
@ BUILD_PAIR
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
@ INIT_TRAMPOLINE
INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
@ FLDEXP
FLDEXP - ldexp, inspired by libm (op0 * 2**op1).
@ STRICT_FSQRT
Constrained versions of libm-equivalent floating point intrinsics.
@ 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.
@ IS_FPCLASS
Performs a check of floating point class property, defined by IEEE-754.
@ SSUBSAT
RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2 integers with the same bit width ...
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ EXTRACT_ELEMENT
EXTRACT_ELEMENT - This is used to get the lower or upper (determined by a Constant,...
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
@ GET_ROUNDING
Returns current rounding mode: -1 Undefined 0 Round to 0 1 Round to nearest, ties to even 2 Round to ...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
@ EXTRACT_SUBVECTOR
EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
@ FMINNUM_IEEE
FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or maximumNumber on two values,...
@ EXTRACT_VECTOR_ELT
EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR identified by the (potentially...
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
@ FMINNUM
FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two values.
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FP_EXTEND
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ VSELECT
Select with a vector condition (op #0) and two vector operands (ops #1 and #2), returning a vector re...
@ STRICT_SINT_TO_FP
STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to a floating point value.
@ INLINEASM_BR
INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
@ EH_DWARF_CFA
EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical Frame Address (CFA),...
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ STRICT_FP_ROUND
X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision ...
@ STRICT_FP_TO_SINT
STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ FP_TO_SINT
FP_TO_[US]INT - Convert a floating point value to a signed or unsigned integer.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ STRICT_FP_EXTEND
X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ TRAP
TRAP - Trapping instruction.
@ INTRINSIC_WO_CHAIN
RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...) This node represents a target intrinsic fun...
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ STRICT_FADD
Constrained versions of the binary floating point operators.
@ INSERT_VECTOR_ELT
INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element at IDX replaced with VAL.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ FP_ROUND
X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type down to the precision of the ...
@ INLINEASM
INLINEASM - Represents an inline asm block.
@ EH_SJLJ_SETJMP
RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer) This corresponds to the eh.sjlj....
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
@ FCOPYSIGN
FCOPYSIGN(X, Y) - Return the value of X with the sign of Y.
@ SADDSAT
RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2 integers with the same bit width (W)...
@ CALLSEQ_START
CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of a call sequence,...
@ GET_DYNAMIC_AREA_OFFSET
GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of the most recent dynamic alloca.
@ 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 isBitwiseLogicOp(unsigned Opcode)
Whether this is bitwise logic opcode.
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isSignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs a signed comparison when used with integer o...
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
bool isUnsignedIntSetCC(CondCode Code)
Return true if this is a setcc instruction that performs an unsigned comparison when used with intege...
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
ID ArrayRef< Type * > Tys
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_PPC_TLS fixup attached to an ADD instruction.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_LO
MO_LO, MO_HA - lo16(symbol) and ha16(symbol)
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_HA_FLAG
MO_PIC_HA_FLAG = MO_PIC_FLAG | MO_HA.
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_PIC_FLAG
MO_PIC_FLAG - If this bit is set, the symbol reference is relative to the function's picbase,...
@ SEXT_LD_SPLAT
VSRC, CHAIN = SEXT_LD_SPLAT, CHAIN, Ptr - a splatting load memory that sign-extends.
@ FCTIDUZ
Newer FCTI[D,W]UZ floating-point-to-integer conversion instructions for unsigned integers with round ...
@ ADDI_TLSGD_L_ADDR
G8RC = ADDI_TLSGD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSGD_L and GET_TLS_ADDR unti...
@ FSQRT
Square root instruction.
@ STRICT_FCFID
Constrained integer-to-floating-point conversion instructions.
@ DYNALLOC
The following two target-specific nodes are used for calls through function pointers in the 64-bit SV...
@ COND_BRANCH
CHAIN = COND_BRANCH CHAIN, CRRC, OPC, DESTBB [, INFLAG] - This corresponds to the COND_BRANCH pseudo ...
@ TLSLD_AIX
[GP|G8]RC = TLSLD_AIX, TOC_ENTRY(module handle) Op that requires a single input of the module handle ...
@ CALL_RM
The variants that implicitly define rounding mode for calls with strictfp semantics.
@ STORE_VEC_BE
CHAIN = STORE_VEC_BE CHAIN, VSRC, Ptr - Occurs only for little endian.
@ BDNZ
CHAIN = BDNZ CHAIN, DESTBB - These are used to create counter-based loops.
@ MTVSRZ
Direct move from a GPR to a VSX register (zero)
@ SRL
These nodes represent PPC shifts.
@ VECINSERT
VECINSERT - The PPC vector insert instruction.
@ LXSIZX
GPRC, CHAIN = LXSIZX, CHAIN, Ptr, ByteWidth - This is a load of an integer smaller than 64 bits into ...
@ FNMSUB
FNMSUB - Negated multiply-subtract instruction.
@ RFEBB
CHAIN = RFEBB CHAIN, State - Return from event-based branch.
@ FCTIDZ
FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking an f32 or f64 operand, producing an f64 value...
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
@ GET_TLS_ADDR
x3 = GET_TLS_ADDR x3, Symbol - For the general-dynamic TLS model, produces a call to __tls_get_addr(s...
@ XXSPLTI32DX
XXSPLTI32DX - The PPC XXSPLTI32DX instruction.
@ ANDI_rec_1_EQ_BIT
i1 = ANDI_rec_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the result of the eq or gt bit of CR0 after ex...
@ FRE
Reciprocal estimate instructions (unary FP ops).
@ ADDIS_GOT_TPREL_HA
G8RC = ADDIS_GOT_TPREL_HA x2, Symbol - Used by the initial-exec TLS model, produces an ADDIS8 instruc...
@ CLRBHRB
CHAIN = CLRBHRB CHAIN - Clear branch history rolling buffer.
@ STORE_COND
CHAIN,Glue = STORE_COND CHAIN, GPR, Ptr The store conditional instruction ST[BHWD]ARX that produces a...
@ SINT_VEC_TO_FP
Extract a subvector from signed integer vector and convert to FP.
@ EXTRACT_SPE
Extract SPE register component, second argument is high or low.
@ XXSWAPD
VSRC, CHAIN = XXSWAPD CHAIN, VSRC - Occurs only for little endian.
@ ADDI_TLSLD_L_ADDR
G8RC = ADDI_TLSLD_L_ADDR G8RReg, Symbol, Symbol - Op that combines ADDI_TLSLD_L and GET_TLSLD_ADDR un...
@ ATOMIC_CMP_SWAP_8
ATOMIC_CMP_SWAP - the exact same as the target-independent nodes except they ensure that the compare ...
@ ST_VSR_SCAL_INT
Store scalar integers from VSR.
@ VCMP
RESVEC = VCMP(LHS, RHS, OPC) - Represents one of the altivec VCMP* instructions.
@ BCTRL
CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a BCTRL instruction.
@ BUILD_SPE64
BUILD_SPE64 and EXTRACT_SPE are analogous to BUILD_PAIR and EXTRACT_ELEMENT but take f64 arguments in...
@ LFIWZX
GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a floating-point load which zero-extends from a 32-bit inte...
@ RET_GLUE
Return with a glue operand, matched by 'blr'.
@ SCALAR_TO_VECTOR_PERMUTED
PowerPC instructions that have SCALAR_TO_VECTOR semantics tend to place the value into the least sign...
@ EXTRACT_VSX_REG
EXTRACT_VSX_REG = Extract one of the underlying vsx registers of an accumulator or pair register.
@ STXSIX
STXSIX - The STXSI[bh]X instruction.
@ MAT_PCREL_ADDR
MAT_PCREL_ADDR = Materialize a PC Relative address.
@ MFOCRF
R32 = MFOCRF(CRREG, INFLAG) - Represents the MFOCRF instruction.
@ XXSPLT
XXSPLT - The PPC VSX splat instructions.
@ TOC_ENTRY
GPRC = TOC_ENTRY GA, TOC Loads the entry for GA from the TOC, where the TOC base is given by the last...
@ XXPERMDI
XXPERMDI - The PPC XXPERMDI instruction.
@ ADDIS_DTPREL_HA
G8RC = ADDIS_DTPREL_HA x3, Symbol - For the local-dynamic TLS model, produces an ADDIS8 instruction t...
@ ADD_TLS
G8RC = ADD_TLS G8RReg, Symbol - Can be used by the initial-exec and local-exec TLS models,...
@ MTVSRA
Direct move from a GPR to a VSX register (algebraic)
@ VADD_SPLAT
VRRC = VADD_SPLAT Elt, EltSize - Temporary node to be expanded during instruction selection to optimi...
@ PPC32_GOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ ADDI_DTPREL_L
G8RC = ADDI_DTPREL_L G8RReg, Symbol - For the local-dynamic TLS model, produces an ADDI8 instruction ...
@ BCTRL_LOAD_TOC
CHAIN,FLAG = BCTRL(CHAIN, ADDR, INFLAG) - The combination of a bctrl instruction and the TOC reload r...
@ PPC32_PICGOT
GPRC = address of GLOBAL_OFFSET_TABLE.
@ FCFID
FCFID - The FCFID instruction, taking an f64 operand and producing and f64 value containing the FP re...
@ CR6SET
ch, gl = CR6[UN]SET ch, inglue - Toggle CR bit 6 for SVR4 vararg calls
@ LBRX
GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a byte-swapping load instruction.
@ GET_TLS_MOD_AIX
x3 = GET_TLS_MOD_AIX _$TLSML - For the AIX local-dynamic TLS model, produces a call to ....
@ 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.
@ TLSGD_AIX
GPRC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY Op that combines two re...
@ UINT_VEC_TO_FP
Extract a subvector from unsigned integer vector and convert to FP.
@ GET_TPOINTER
x3 = GET_TPOINTER - Used for the local- and initial-exec TLS model on 32-bit AIX, produces a call to ...
@ LXVRZX
LXVRZX - Load VSX Vector Rightmost and Zero Extend This node represents v1i128 BUILD_VECTOR of a zero...
@ MFBHRBE
GPRC, CHAIN = MFBHRBE CHAIN, Entry, Dummy - Move from branch history rolling buffer entry.
@ FCFIDU
Newer FCFID[US] integer-to-floating-point conversion instructions for unsigned integers and single-pr...
@ FSEL
FSEL - Traditional three-operand fsel node.
@ SWAP_NO_CHAIN
An SDNode for swaps that are not associated with any loads/stores and thereby have no chain.
@ LOAD_VEC_BE
VSRC, CHAIN = LOAD_VEC_BE CHAIN, Ptr - Occurs only for little endian.
@ LFIWAX
GPRC, CHAIN = LFIWAX CHAIN, Ptr - This is a floating-point load which sign-extends from a 32-bit inte...
@ LD_GOT_TPREL_L
G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec TLS model, produces a LD instruction ...
@ MFVSR
Direct move from a VSX register to a GPR.
@ TLS_DYNAMIC_MAT_PCREL_ADDR
TLS_DYNAMIC_MAT_PCREL_ADDR = Materialize a PC Relative address for TLS global address when using dyna...
@ Hi
Hi/Lo - These represent the high and low 16-bit parts of a global address respectively.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
SDValue get_VSPLTI_elt(SDNode *N, unsigned ByteSize, SelectionDAG &DAG)
get_VSPLTI_elt - If this is a build_vector of constants which can be formed by using a vspltis[bhw] i...
bool isXXBRDShuffleMask(ShuffleVectorSDNode *N)
isXXBRDShuffleMask - Return true if this is a shuffle mask suitable for a XXBRD instruction.
FastISel * createFastISel(FunctionLoweringInfo &FuncInfo, const TargetLibraryInfo *LibInfo)
bool isVMRGHShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for a VRGH* instruction with the ...
bool isVPKUDUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUDUMShuffleMask - Return true if this is the shuffle mask for a VPKUDUM instruction.
bool isVMRGEOShuffleMask(ShuffleVectorSDNode *N, bool CheckEven, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGEOShuffleMask - Return true if this is a shuffle mask suitable for a VMRGEW or VMRGOW instructi...
bool isXXBRQShuffleMask(ShuffleVectorSDNode *N)
isXXBRQShuffleMask - Return true if this is a shuffle mask suitable for a XXBRQ instruction.
bool isXXBRWShuffleMask(ShuffleVectorSDNode *N)
isXXBRWShuffleMask - Return true if this is a shuffle mask suitable for a XXBRW instruction.
bool isXXPERMDIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXPERMDIShuffleMask - Return true if this is a shuffle mask suitable for a XXPERMDI instruction.
bool isXXBRHShuffleMask(ShuffleVectorSDNode *N)
isXXBRHShuffleMask - Return true if this is a shuffle mask suitable for a XXBRH instruction.
unsigned getSplatIdxForPPCMnemonics(SDNode *N, unsigned EltSize, SelectionDAG &DAG)
getSplatIdxForPPCMnemonics - Return the splat index as a value that is appropriate for PPC mnemonics ...
bool isXXSLDWIShuffleMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, bool &Swap, bool IsLE)
isXXSLDWIShuffleMask - Return true if this is a shuffle mask suitable for a XXSLDWI instruction.
int isVSLDOIShuffleMask(SDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift amount, otherwise return -1.
bool isVMRGLShuffleMask(ShuffleVectorSDNode *N, unsigned UnitSize, unsigned ShuffleKind, SelectionDAG &DAG)
isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for a VRGL* instruction with the ...
bool isXXINSERTWMask(ShuffleVectorSDNode *N, unsigned &ShiftElts, unsigned &InsertAtByte, bool &Swap, bool IsLE)
isXXINSERTWMask - Return true if this VECTOR_SHUFFLE can be handled by the XXINSERTW instruction intr...
bool isSplatShuffleMask(ShuffleVectorSDNode *N, unsigned EltSize)
isSplatShuffleMask - Return true if the specified VECTOR_SHUFFLE operand specifies a splat of a singl...
bool isVPKUWUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a VPKUWUM instruction.
bool isVPKUHUMShuffleMask(ShuffleVectorSDNode *N, unsigned ShuffleKind, SelectionDAG &DAG)
isVPKUHUMShuffleMask - Return true if this is the shuffle mask for a VPKUHUM instruction.
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
const_iterator end(StringRef path 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)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.