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);
7873 CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context);
7874 return CCInfo.CheckReturn(
7889 CCInfo.AnalyzeReturn(Outs,
7898 for (
unsigned i = 0, RealResIdx = 0; i != RVLocs.
size(); ++i, ++RealResIdx) {
7902 SDValue Arg = OutVals[RealResIdx];
7917 if (Subtarget.hasSPE() && VA.
getLocVT() == MVT::f64) {
7940 RetOps.push_back(Glue);
7946PPCTargetLowering::LowerGET_DYNAMIC_AREA_OFFSET(
SDValue Op,
7951 EVT IntVT =
Op.getValueType();
7955 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
7957 SDValue Ops[2] = {Chain, FPSIdx};
7971 bool isPPC64 = Subtarget.
isPPC64();
7972 unsigned SP = isPPC64 ? PPC::X1 : PPC::R1;
7992 bool isPPC64 = Subtarget.
isPPC64();
8013PPCTargetLowering::getFramePointerFrameIndex(
SelectionDAG & DAG)
const {
8015 bool isPPC64 = Subtarget.
isPPC64();
8049 SDValue FPSIdx = getFramePointerFrameIndex(DAG);
8050 SDValue Ops[3] = { Chain, NegSize, FPSIdx };
8061 bool isPPC64 = Subtarget.
isPPC64();
8073 Op.getOperand(0),
Op.getOperand(1));
8080 Op.getOperand(0),
Op.getOperand(1));
8084 if (
Op.getValueType().isVector())
8085 return LowerVectorLoad(
Op, DAG);
8087 assert(
Op.getValueType() == MVT::i1 &&
8088 "Custom lowering only for i1 loads");
8101 BasePtr, MVT::i8, MMO);
8109 if (
Op.getOperand(1).getValueType().isVector())
8110 return LowerVectorStore(
Op, DAG);
8112 assert(
Op.getOperand(1).getValueType() == MVT::i1 &&
8113 "Custom lowering only for i1 stores");
8132 assert(
Op.getValueType() == MVT::i1 &&
8133 "Custom lowering only for i1 results");
8161 EVT TrgVT =
Op.getValueType();
8174 !llvm::has_single_bit<uint32_t>(
8185 if (SrcSize == 256) {
8196 Op1 = SrcSize == 128 ? N1 :
widenVec(DAG, N1,
DL);
8204 for (
unsigned i = 0; i < TrgNumElts; ++i)
8207 for (
unsigned i = 1; i <= TrgNumElts; ++i)
8211 for (
unsigned i = TrgNumElts; i < WideNumElts; ++i)
8224 EVT ResVT =
Op.getValueType();
8225 EVT CmpVT =
Op.getOperand(0).getValueType();
8227 SDValue TV =
Op.getOperand(2), FV =
Op.getOperand(3);
8233 if (!Subtarget.hasP9Vector() && CmpVT == MVT::f128) {
8250 if (Subtarget.hasP9Vector() && LHS == TV && RHS == FV) {
8282 if (
LHS.getValueType() == MVT::f32)
8295 if (
LHS.getValueType() == MVT::f32)
8304 if (
LHS.getValueType() == MVT::f32)
8318 if (
Cmp.getValueType() == MVT::f32)
8328 if (
Cmp.getValueType() == MVT::f32)
8334 if (
Cmp.getValueType() == MVT::f32)
8340 if (
Cmp.getValueType() == MVT::f32)
8346 if (
Cmp.getValueType() == MVT::f32)
8379 bool IsStrict =
Op->isStrictFPOpcode();
8385 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8388 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8390 MVT DestTy =
Op.getSimpleValueType();
8391 assert(Src.getValueType().isFloatingPoint() &&
8392 (DestTy == MVT::i8 || DestTy == MVT::i16 || DestTy == MVT::i32 ||
8393 DestTy == MVT::i64) &&
8394 "Invalid FP_TO_INT types");
8395 if (Src.getValueType() == MVT::f32) {
8399 DAG.
getVTList(MVT::f64, MVT::Other), {Chain, Src}, Flags);
8400 Chain = Src.getValue(1);
8404 if ((DestTy == MVT::i8 || DestTy == MVT::i16) && Subtarget.hasP9Vector())
8414 assert((IsSigned || Subtarget.hasFPCVT()) &&
8415 "i64 FP_TO_UINT is supported only with FPCVT");
8418 EVT ConvTy = Src.getValueType() == MVT::f128 ? MVT::f128 : MVT::f64;
8422 Conv = DAG.
getNode(Opc, dl, DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src},
8425 Conv = DAG.
getNode(Opc, dl, ConvTy, Src);
8430void PPCTargetLowering::LowerFP_TO_INTForReuse(
SDValue Op, ReuseLoadInfo &RLI,
8432 const SDLoc &dl)
const {
8436 bool IsStrict =
Op->isStrictFPOpcode();
8439 bool i32Stack =
Op.getValueType() == MVT::i32 && Subtarget.hasSTFIWX() &&
8440 (IsSigned || Subtarget.hasFPCVT());
8442 int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
8451 Alignment =
Align(4);
8454 SDValue Ops[] = { Chain, Tmp, FIPtr };
8456 DAG.
getVTList(MVT::Other), Ops, MVT::i32, MMO);
8458 Chain = DAG.
getStore(Chain, dl, Tmp, FIPtr, MPI, Alignment);
8462 if (
Op.getValueType() == MVT::i32 && !i32Stack) {
8471 RLI.Alignment = Alignment;
8479 const SDLoc &dl)
const {
8482 if (
Op->isStrictFPOpcode())
8489 const SDLoc &dl)
const {
8490 bool IsStrict =
Op->isStrictFPOpcode();
8493 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8494 EVT SrcVT = Src.getValueType();
8495 EVT DstVT =
Op.getValueType();
8498 if (SrcVT == MVT::f128)
8499 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8503 if (SrcVT == MVT::ppcf128) {
8504 if (DstVT == MVT::i32) {
8509 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8520 {Op.getOperand(0), Lo, Hi}, Flags);
8523 {Res.getValue(1), Res}, Flags);
8529 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
8553 {Chain, Src, FltOfs}, Flags);
8557 {Chain, Val}, Flags);
8560 dl, DstVT, Sel, DAG.
getConstant(0, dl, DstVT), SignMask);
8578 if (Subtarget.hasDirectMove() && Subtarget.
isPPC64())
8579 return LowerFP_TO_INTDirectMove(
Op, DAG, dl);
8582 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8584 return DAG.
getLoad(
Op.getValueType(), dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8585 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8596bool PPCTargetLowering::canReuseLoadAddress(
SDValue Op,
EVT MemVT,
8601 if (
Op->isStrictFPOpcode())
8606 (Subtarget.hasFPCVT() ||
Op.getValueType() == MVT::i32);
8610 Op.getOperand(0).getValueType())) {
8612 LowerFP_TO_INTForReuse(
Op, RLI, DAG, dl);
8617 if (!LD ||
LD->getExtensionType() != ET ||
LD->isVolatile() ||
8618 LD->isNonTemporal())
8620 if (
LD->getMemoryVT() != MemVT)
8630 RLI.Ptr =
LD->getBasePtr();
8631 if (
LD->isIndexed() && !
LD->getOffset().isUndef()) {
8633 "Non-pre-inc AM on PPC?");
8638 RLI.Chain =
LD->getChain();
8639 RLI.MPI =
LD->getPointerInfo();
8640 RLI.IsDereferenceable =
LD->isDereferenceable();
8641 RLI.IsInvariant =
LD->isInvariant();
8642 RLI.Alignment =
LD->getAlign();
8643 RLI.AAInfo =
LD->getAAInfo();
8644 RLI.Ranges =
LD->getRanges();
8646 RLI.ResChain =
SDValue(LD,
LD->isIndexed() ? 2 : 1);
8654void PPCTargetLowering::spliceIntoChain(
SDValue ResChain,
8660 SDLoc dl(NewResChain);
8663 NewResChain, DAG.
getUNDEF(MVT::Other));
8665 "A new TF really is required here");
8674bool PPCTargetLowering::directMoveIsProfitable(
const SDValue &
Op)
const {
8675 SDNode *Origin =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0).getNode();
8682 if (!Subtarget.hasP9Vector() &&
8689 if (
Use.getResNo() != 0)
8712 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8716 bool IsSingle =
Op.getValueType() == MVT::f32 && Subtarget.hasFPCVT();
8719 EVT ConvTy = IsSingle ? MVT::f32 : MVT::f64;
8720 if (
Op->isStrictFPOpcode()) {
8722 Chain =
Op.getOperand(0);
8724 DAG.
getVTList(ConvTy, MVT::Other), {Chain, Src}, Flags);
8726 return DAG.
getNode(ConvOpc, dl, ConvTy, Src);
8734 const SDLoc &dl)
const {
8735 assert((
Op.getValueType() == MVT::f32 ||
8736 Op.getValueType() == MVT::f64) &&
8737 "Invalid floating point type as target of conversion");
8738 assert(Subtarget.hasFPCVT() &&
8739 "Int to FP conversions with direct moves require FPCVT");
8740 SDValue Src =
Op.getOperand(
Op->isStrictFPOpcode() ? 1 : 0);
8741 bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
8763 for (
unsigned i = 1; i < NumConcat; ++i)
8770 const SDLoc &dl)
const {
8771 bool IsStrict =
Op->isStrictFPOpcode();
8772 unsigned Opc =
Op.getOpcode();
8773 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8776 "Unexpected conversion type");
8777 assert((
Op.getValueType() == MVT::v2f64 ||
Op.getValueType() == MVT::v4f32) &&
8778 "Supports conversions to v2f64/v4f32 only.");
8782 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8785 bool FourEltRes =
Op.getValueType() == MVT::v4f32;
8790 MVT IntermediateVT = FourEltRes ? MVT::v4i32 : MVT::v2i64;
8793 for (
unsigned i = 0; i < WideNumElts; ++i)
8796 int Stride = FourEltRes ? WideNumElts / 4 : WideNumElts / 2;
8797 int SaveElts = FourEltRes ? 4 : 2;
8799 for (
int i = 0; i < SaveElts; i++)
8800 ShuffV[i * Stride] = i;
8802 for (
int i = 1; i <= SaveElts; i++)
8803 ShuffV[i * Stride - 1] = i - 1;
8811 Arrange = DAG.
getBitcast(IntermediateVT, Arrange);
8812 EVT ExtVT = Src.getValueType();
8813 if (Subtarget.hasP9Altivec())
8824 {Op.getOperand(0), Extend}, Flags);
8826 return DAG.
getNode(Opc, dl,
Op.getValueType(), Extend);
8834 bool IsStrict =
Op->isStrictFPOpcode();
8835 SDValue Src =
Op.getOperand(IsStrict ? 1 : 0);
8840 Flags.setNoFPExcept(
Op->getFlags().hasNoFPExcept());
8842 EVT InVT = Src.getValueType();
8843 EVT OutVT =
Op.getValueType();
8846 return LowerINT_TO_FPVector(
Op, DAG, dl);
8849 if (
Op.getValueType() == MVT::f128)
8850 return Subtarget.hasP9Vector() ?
Op :
SDValue();
8853 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
8856 if (Src.getValueType() == MVT::i1) {
8868 if (Subtarget.hasDirectMove() && directMoveIsProfitable(
Op) &&
8869 Subtarget.
isPPC64() && Subtarget.hasFPCVT())
8870 return LowerINT_TO_FPDirectMove(
Op, DAG, dl);
8872 assert((IsSigned || Subtarget.hasFPCVT()) &&
8873 "UINT_TO_FP is supported only with FPCVT");
8875 if (Src.getValueType() == MVT::i64) {
8887 if (
Op.getValueType() == MVT::f32 &&
8888 !Subtarget.hasFPCVT() &&
8929 if (canReuseLoadAddress(SINT, MVT::i64, RLI, DAG)) {
8930 Bits = DAG.
getLoad(MVT::f64, dl, RLI.Chain, RLI.Ptr, RLI.MPI,
8931 RLI.Alignment, RLI.MMOFlags(), RLI.AAInfo, RLI.Ranges);
8932 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8933 }
else if (Subtarget.hasLFIWAX() &&
8934 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::SEXTLOAD)) {
8937 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8938 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8941 Ops, MVT::i32, MMO);
8942 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8943 }
else if (Subtarget.hasFPCVT() &&
8944 canReuseLoadAddress(SINT, MVT::i32, RLI, DAG,
ISD::ZEXTLOAD)) {
8947 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8948 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8951 Ops, MVT::i32, MMO);
8952 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
8953 }
else if (((Subtarget.hasLFIWAX() &&
8955 (Subtarget.hasFPCVT() &&
8969 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
8970 "Expected an i32 store");
8976 RLI.Alignment =
Align(4);
8980 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
8981 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
8984 dl, DAG.
getVTList(MVT::f64, MVT::Other),
8985 Ops, MVT::i32, MMO);
8986 Chain =
Bits.getValue(1);
8992 Chain =
FP.getValue(1);
8994 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
8998 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)},
9007 assert(Src.getValueType() == MVT::i32 &&
9008 "Unhandled INT_TO_FP type in custom expander!");
9018 if (Subtarget.hasLFIWAX() || Subtarget.hasFPCVT()) {
9021 if (!(ReusingLoad = canReuseLoadAddress(Src, MVT::i32, RLI, DAG))) {
9030 assert(cast<StoreSDNode>(Store)->getMemoryVT() == MVT::i32 &&
9031 "Expected an i32 store");
9037 RLI.Alignment =
Align(4);
9042 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
9043 SDValue Ops[] = { RLI.Chain, RLI.Ptr };
9045 DAG.
getVTList(MVT::f64, MVT::Other), Ops,
9049 spliceIntoChain(RLI.ResChain, Ld.
getValue(1), DAG);
9052 "i32->FP without LFIWAX supported only on PPC64");
9061 Chain, dl, Ext64, FIdx,
9067 MVT::f64, dl, Chain, FIdx,
9075 Chain =
FP.getValue(1);
9076 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
9080 {Chain, FP, DAG.getIntPtrConstant(0, dl, true)}, Flags);
9096 if (
auto *CVal = dyn_cast<ConstantSDNode>(
Op.getOperand(1))) {
9098 assert(Mode < 4 &&
"Unsupported rounding mode!");
9099 unsigned InternalRnd =
Mode ^ (~(
Mode >> 1) & 1);
9100 if (Subtarget.isISA3_0())
9103 PPC::MFFSCRNI, Dl, {MVT::f64, MVT::Other},
9104 {DAG.getConstant(InternalRnd, Dl, MVT::i32, true), Chain}),
9107 (InternalRnd & 2) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9108 {DAG.
getConstant(30, Dl, MVT::i32,
true), Chain});
9110 (InternalRnd & 1) ? PPC::MTFSB1 : PPC::MTFSB0, Dl, MVT::Other,
9128 if (!Subtarget.isISA3_0()) {
9130 Chain =
MFFS.getValue(1);
9134 if (Subtarget.isISA3_0()) {
9139 PPC::RLDIMI, Dl, MVT::i64,
9144 NewFPSCR =
SDValue(InsertRN, 0);
9155 if (Subtarget.isISA3_0()) {
9163 PPC::RLWIMI, Dl, MVT::i32,
9164 {Tmp, DstFlag, DAG.getTargetConstant(0, Dl, MVT::i32),
9165 DAG.getTargetConstant(30, Dl, MVT::i32),
9166 DAG.getTargetConstant(31, Dl, MVT::i32)}),
9174 if (Subtarget.isISA3_0())
9180 PPC::MTFSF, Dl, MVT::Other,
9181 {DAG.
getConstant(255, Dl, MVT::i32,
true), NewFPSCR, Zero, Zero, Chain});
9208 EVT VT =
Op.getValueType();
9214 Chain =
MFFS.getValue(1);
9228 "Stack slot adjustment is valid only on big endian subtargets!");
9258 EVT VT =
Op.getValueType();
9262 VT ==
Op.getOperand(1).getValueType() &&
9282 SDValue OutOps[] = { OutLo, OutHi };
9287 EVT VT =
Op.getValueType();
9291 VT ==
Op.getOperand(1).getValueType() &&
9311 SDValue OutOps[] = { OutLo, OutHi };
9317 EVT VT =
Op.getValueType();
9320 VT ==
Op.getOperand(1).getValueType() &&
9340 SDValue OutOps[] = { OutLo, OutHi };
9347 EVT VT =
Op.getValueType();
9354 EVT AmtVT =
Z.getValueType();
9377 static const MVT VTys[] = {
9378 MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32
9381 EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1];
9384 if (Val == ((1LLU << (SplatSize * 8)) - 1)) {
9389 EVT CanonicalVT = VTys[SplatSize-1];
9402 const SDLoc &dl,
EVT DestVT = MVT::Other) {
9403 if (DestVT == MVT::Other) DestVT =
Op.getValueType();
9412 EVT DestVT = MVT::Other) {
9413 if (DestVT == MVT::Other) DestVT =
LHS.getValueType();
9422 EVT DestVT = MVT::Other) {
9425 DAG.
getConstant(IID, dl, MVT::i32), Op0, Op1, Op2);
9437 for (
unsigned i = 0; i != 16; ++i)
9458 EVT VecVT = V->getValueType(0);
9459 bool RightType = VecVT == MVT::v2f64 ||
9460 (HasP8Vector && VecVT == MVT::v4f32) ||
9461 (HasDirectMove && (VecVT == MVT::v2i64 || VecVT == MVT::v4i32));
9465 bool IsSplat =
true;
9466 bool IsLoad =
false;
9467 SDValue Op0 = V->getOperand(0);
9472 if (V->isConstant())
9474 for (
int i = 0, e = V->getNumOperands(); i < e; ++i) {
9475 if (V->getOperand(i).isUndef())
9479 if (V->getOperand(i).getOpcode() ==
ISD::LOAD ||
9481 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9483 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD) ||
9485 V->getOperand(i).getOperand(0).getOpcode() ==
ISD::LOAD))
9489 if (V->getOperand(i) != Op0 ||
9490 (!IsLoad && !V->isOnlyUserOf(V->getOperand(i).getNode())))
9493 return !(IsSplat && IsLoad);
9503 (
Op.getValueType() != MVT::f128))
9508 if ((
Lo.getValueType() != MVT::i64) || (
Hi.getValueType() != MVT::i64))
9528 LoadSDNode *LD = cast<LoadSDNode>(*InputLoad);
9536 APFloat APFloatToConvert = ArgAPFloat;
9537 bool LosesInfo =
true;
9542 ArgAPFloat = APFloatToConvert;
9564 APFloat APFloatToConvert = ArgAPFloat;
9565 bool LosesInfo =
true;
9569 return (!LosesInfo && !APFloatToConvert.
isDenormal());
9574 LoadSDNode *InputNode = dyn_cast<LoadSDNode>(
Op.getOperand(0));
9578 EVT Ty =
Op->getValueType(0);
9581 if ((Ty == MVT::v2f64 || Ty == MVT::v4f32 || Ty == MVT::v4i32) &&
9590 if ((Ty == MVT::v8i16 || Ty == MVT::v16i8) &&
ISD::isEXTLoad(InputNode) &&
9594 if (Ty == MVT::v2i64) {
9597 if (MemVT == MVT::i32) {
9617 assert(BVN &&
"Expected a BuildVectorSDNode in LowerBUILD_VECTOR");
9620 APInt APSplatBits, APSplatUndef;
9621 unsigned SplatBitSize;
9623 bool BVNIsConstantSplat =
9631 if (BVNIsConstantSplat && (SplatBitSize == 64) &&
9632 Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
9635 if ((
Op->getValueType(0) == MVT::v2f64) &&
9668 if (!BVNIsConstantSplat || SplatBitSize > 32) {
9675 const SDValue *InputLoad = &
Op.getOperand(0);
9680 unsigned MemorySize =
LD->getMemoryVT().getScalarSizeInBits();
9681 unsigned ElementSize =
9684 assert(((ElementSize == 2 * MemorySize)
9688 "Unmatched element size and opcode!\n");
9693 unsigned NumUsesOfInputLD = 128 / ElementSize;
9695 if (BVInOp.isUndef())
9710 if (NumUsesOfInputLD == 1 &&
9713 Subtarget.hasLFIWAX()))
9722 Subtarget.isISA3_1() && ElementSize <= 16)
9725 assert(NumUsesOfInputLD > 0 &&
"No uses of input LD of a build_vector?");
9727 Subtarget.hasVSX()) {
9734 NewOpcode, dl, DAG.
getVTList(
Op.getValueType(), MVT::Other), Ops,
9735 LD->getMemoryVT(),
LD->getMemOperand());
9747 if (Subtarget.hasVSX() && Subtarget.
isPPC64() &&
9749 Subtarget.hasP8Vector()))
9756 unsigned SplatSize = SplatBitSize / 8;
9761 if (SplatBits == 0) {
9763 if (
Op.getValueType() != MVT::v4i32 || HasAnyUndefs) {
9775 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 2)
9777 Op.getValueType(), DAG, dl);
9779 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector() && SplatSize == 4)
9784 if (Subtarget.hasP9Vector() && SplatSize == 1)
9789 int32_t SextVal =
SignExtend32(SplatBits, SplatBitSize);
9790 if (SextVal >= -16 && SextVal <= 15)
9803 if (SextVal >= -32 && SextVal <= 31) {
9808 EVT VT = (SplatSize == 1 ? MVT::v16i8 :
9809 (SplatSize == 2 ? MVT::v8i16 : MVT::v4i32));
9812 if (VT ==
Op.getValueType())
9821 if (SplatSize == 4 && SplatBits == (0x7FFFFFFF&~SplatUndef)) {
9835 static const signed char SplatCsts[] = {
9836 -1, 1, -2, 2, -3, 3, -4, 4, -5, 5, -6, 6, -7, 7,
9837 -8, 8, -9, 9, -10, 10, -11, 11, -12, 12, -13, 13, 14, -14, 15, -15, -16
9840 for (
unsigned idx = 0; idx < std::size(SplatCsts); ++idx) {
9843 int i = SplatCsts[idx];
9847 unsigned TypeShiftAmt = i & (SplatBitSize-1);
9850 if (SextVal == (
int)((
unsigned)i << TypeShiftAmt)) {
9852 static const unsigned IIDs[] = {
9853 Intrinsic::ppc_altivec_vslb, Intrinsic::ppc_altivec_vslh, 0,
9854 Intrinsic::ppc_altivec_vslw
9861 if (SextVal == (
int)((
unsigned)i >> TypeShiftAmt)) {
9863 static const unsigned IIDs[] = {
9864 Intrinsic::ppc_altivec_vsrb, Intrinsic::ppc_altivec_vsrh, 0,
9865 Intrinsic::ppc_altivec_vsrw
9872 if (SextVal == (
int)(((
unsigned)i << TypeShiftAmt) |
9873 ((
unsigned)i >> (SplatBitSize-TypeShiftAmt)))) {
9875 static const unsigned IIDs[] = {
9876 Intrinsic::ppc_altivec_vrlb, Intrinsic::ppc_altivec_vrlh, 0,
9877 Intrinsic::ppc_altivec_vrlw
9884 if (SextVal == (
int)(((
unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
9890 if (SextVal == (
int)(((
unsigned)i << 16) | (i < 0 ? 0xFFFF : 0))) {
9896 if (SextVal == (
int)(((
unsigned)i << 24) | (i < 0 ? 0xFFFFFF : 0))) {
9911 unsigned OpNum = (PFEntry >> 26) & 0x0F;
9912 unsigned LHSID = (PFEntry >> 13) & ((1 << 13)-1);
9913 unsigned RHSID = (PFEntry >> 0) & ((1 << 13)-1);
9929 if (LHSID == (1*9+2)*9+3)
return LHS;
9930 assert(LHSID == ((4*9+5)*9+6)*9+7 &&
"Illegal OP_COPY!");
9942 ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3;
9943 ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19;
9944 ShufIdxs[ 8] = 4; ShufIdxs[ 9] = 5; ShufIdxs[10] = 6; ShufIdxs[11] = 7;
9945 ShufIdxs[12] = 20; ShufIdxs[13] = 21; ShufIdxs[14] = 22; ShufIdxs[15] = 23;
9948 ShufIdxs[ 0] = 8; ShufIdxs[ 1] = 9; ShufIdxs[ 2] = 10; ShufIdxs[ 3] = 11;
9949 ShufIdxs[ 4] = 24; ShufIdxs[ 5] = 25; ShufIdxs[ 6] = 26; ShufIdxs[ 7] = 27;
9950 ShufIdxs[ 8] = 12; ShufIdxs[ 9] = 13; ShufIdxs[10] = 14; ShufIdxs[11] = 15;
9951 ShufIdxs[12] = 28; ShufIdxs[13] = 29; ShufIdxs[14] = 30; ShufIdxs[15] = 31;
9954 for (
unsigned i = 0; i != 16; ++i)
9955 ShufIdxs[i] = (i&3)+0;
9958 for (
unsigned i = 0; i != 16; ++i)
9959 ShufIdxs[i] = (i&3)+4;
9962 for (
unsigned i = 0; i != 16; ++i)
9963 ShufIdxs[i] = (i&3)+8;
9966 for (
unsigned i = 0; i != 16; ++i)
9967 ShufIdxs[i] = (i&3)+12;
9988 const unsigned BytesInVector = 16;
9993 unsigned ShiftElts = 0, InsertAtByte = 0;
9997 unsigned LittleEndianShifts[] = {8, 7, 6, 5, 4, 3, 2, 1,
9998 0, 15, 14, 13, 12, 11, 10, 9};
9999 unsigned BigEndianShifts[] = {9, 10, 11, 12, 13, 14, 15, 0,
10000 1, 2, 3, 4, 5, 6, 7, 8};
10003 int OriginalOrder[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
10015 bool FoundCandidate =
false;
10019 unsigned VINSERTBSrcElem = IsLE ? 8 : 7;
10022 for (
unsigned i = 0; i < BytesInVector; ++i) {
10023 unsigned CurrentElement =
Mask[i];
10026 if (
V2.isUndef() && CurrentElement != VINSERTBSrcElem)
10029 bool OtherElementsInOrder =
true;
10032 for (
unsigned j = 0;
j < BytesInVector; ++
j) {
10039 (!
V2.isUndef() && CurrentElement < BytesInVector) ? BytesInVector : 0;
10040 if (Mask[j] != OriginalOrder[j] + MaskOffset) {
10041 OtherElementsInOrder =
false;
10048 if (OtherElementsInOrder) {
10050 if (
V2.isUndef()) {
10055 ShiftElts = IsLE ? LittleEndianShifts[CurrentElement & 0xF]
10056 : BigEndianShifts[CurrentElement & 0xF];
10057 Swap = CurrentElement < BytesInVector;
10059 InsertAtByte = IsLE ? BytesInVector - (i + 1) : i;
10060 FoundCandidate =
true;
10065 if (!FoundCandidate)
10089 const unsigned NumHalfWords = 8;
10090 const unsigned BytesInVector = NumHalfWords * 2;
10099 unsigned ShiftElts = 0, InsertAtByte = 0;
10103 unsigned LittleEndianShifts[] = {4, 3, 2, 1, 0, 7, 6, 5};
10104 unsigned BigEndianShifts[] = {5, 6, 7, 0, 1, 2, 3, 4};
10107 uint32_t OriginalOrderLow = 0x1234567;
10108 uint32_t OriginalOrderHigh = 0x89ABCDEF;
10111 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10112 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10129 bool FoundCandidate =
false;
10132 for (
unsigned i = 0; i < NumHalfWords; ++i) {
10133 unsigned MaskShift = (NumHalfWords - 1 - i) * 4;
10141 if (
V2.isUndef()) {
10143 unsigned VINSERTHSrcElem = IsLE ? 4 : 3;
10144 TargetOrder = OriginalOrderLow;
10148 if (MaskOneElt == VINSERTHSrcElem &&
10149 (Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10150 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10151 FoundCandidate =
true;
10157 (MaskOneElt < NumHalfWords) ? OriginalOrderHigh : OriginalOrderLow;
10159 if ((Mask & MaskOtherElts) == (TargetOrder & MaskOtherElts)) {
10161 ShiftElts = IsLE ? LittleEndianShifts[MaskOneElt & 0x7]
10162 : BigEndianShifts[MaskOneElt & 0x7];
10163 InsertAtByte = IsLE ? BytesInVector - (i + 1) * 2 : i * 2;
10164 Swap = MaskOneElt < NumHalfWords;
10165 FoundCandidate =
true;
10171 if (!FoundCandidate)
10206 auto ShuffleMask = SVN->
getMask();
10221 ShuffleMask = CommutedSV->
getMask();
10230 APInt APSplatValue, APSplatUndef;
10231 unsigned SplatBitSize;
10247 if ((ShuffleMask[0] == 0 && ShuffleMask[8] == 8) &&
10248 (ShuffleMask[4] % 4 == 0 && ShuffleMask[12] % 4 == 0 &&
10249 ShuffleMask[4] > 15 && ShuffleMask[12] > 15))
10251 else if ((ShuffleMask[4] == 4 && ShuffleMask[12] == 12) &&
10252 (ShuffleMask[0] % 4 == 0 && ShuffleMask[8] % 4 == 0 &&
10253 ShuffleMask[0] > 15 && ShuffleMask[8] > 15))
10261 for (; SplatBitSize < 32; SplatBitSize <<= 1)
10262 SplatVal |= (SplatVal << SplatBitSize);
10276 assert(
Op.getValueType() == MVT::v1i128 &&
10277 "Only set v1i128 as custom, other type shouldn't reach here!");
10282 if (SHLAmt % 8 == 0) {
10283 std::array<int, 16>
Mask;
10284 std::iota(
Mask.begin(),
Mask.end(), 0);
10285 std::rotate(
Mask.begin(),
Mask.begin() + SHLAmt / 8,
Mask.end());
10314 if (
SDValue NewShuffle = combineVectorShuffle(SVOp, DAG)) {
10315 if (!isa<ShuffleVectorSDNode>(NewShuffle))
10318 SVOp = cast<ShuffleVectorSDNode>(
Op);
10319 V1 =
Op.getOperand(0);
10320 V2 =
Op.getOperand(1);
10322 EVT VT =
Op.getValueType();
10325 unsigned ShiftElts, InsertAtByte;
10331 bool IsPermutedLoad =
false;
10333 if (InputLoad && Subtarget.hasVSX() &&
V2.isUndef() &&
10343 if (IsPermutedLoad) {
10344 assert((isLittleEndian || IsFourByte) &&
10345 "Unexpected size for permuted load on big endian target");
10346 SplatIdx += IsFourByte ? 2 : 1;
10347 assert((SplatIdx < (IsFourByte ? 4 : 2)) &&
10348 "Splat of a value outside of the loaded memory");
10353 if ((IsFourByte && Subtarget.hasP9Vector()) || !IsFourByte) {
10356 Offset = isLittleEndian ? (3 - SplatIdx) * 4 : SplatIdx * 4;
10358 Offset = isLittleEndian ? (1 - SplatIdx) * 8 : SplatIdx * 8;
10362 if (
LD->getValueType(0).getSizeInBits() == (IsFourByte ? 32 : 64))
10375 DAG.
getVTList(IsFourByte ? MVT::v4i32 : MVT::v2i64, MVT::Other);
10378 Ops,
LD->getMemoryVT(),
LD->getMemOperand());
10387 if (VT == MVT::v2i64 || VT == MVT::v2f64)
10390 if (Subtarget.hasP9Vector() &&
10411 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
10413 if ((SplatInsertNode = lowerToXXSPLTI32DX(SVOp, DAG)))
10414 return SplatInsertNode;
10417 if (Subtarget.hasP9Altivec()) {
10419 if ((NewISDNode = lowerToVINSERTH(SVOp, DAG)))
10422 if ((NewISDNode = lowerToVINSERTB(SVOp, DAG)))
10426 if (Subtarget.hasVSX() &&
10439 if (Subtarget.hasVSX() &&
10452 if (Subtarget.hasP9Vector()) {
10472 if (Subtarget.hasVSX()) {
10493 if (
V2.isUndef()) {
10506 (Subtarget.hasP8Altivec() && (
10517 unsigned int ShuffleKind = isLittleEndian ? 2 : 0;
10527 (Subtarget.hasP8Altivec() && (
10538 unsigned PFIndexes[4];
10539 bool isFourElementShuffle =
true;
10540 for (
unsigned i = 0; i != 4 && isFourElementShuffle;
10542 unsigned EltNo = 8;
10543 for (
unsigned j = 0;
j != 4; ++
j) {
10544 if (PermMask[i * 4 + j] < 0)
10547 unsigned ByteSource = PermMask[i * 4 +
j];
10548 if ((ByteSource & 3) != j) {
10549 isFourElementShuffle =
false;
10554 EltNo = ByteSource / 4;
10555 }
else if (EltNo != ByteSource / 4) {
10556 isFourElementShuffle =
false;
10560 PFIndexes[i] = EltNo;
10568 if (isFourElementShuffle) {
10570 unsigned PFTableIndex = PFIndexes[0] * 9 * 9 * 9 + PFIndexes[1] * 9 * 9 +
10571 PFIndexes[2] * 9 + PFIndexes[3];
10574 unsigned Cost = (PFEntry >> 30);
10594 if (
V2.isUndef())
V2 = V1;
10596 return LowerVPERM(
Op, DAG, PermMask, VT, V1, V2);
10605 bool NeedSwap =
false;
10607 bool isPPC64 = Subtarget.
isPPC64();
10609 if (Subtarget.hasVSX() && Subtarget.hasP9Vector() &&
10611 LLVM_DEBUG(
dbgs() <<
"At least one of two input vectors are dead - using "
10612 "XXPERM instead\n");
10618 if ((!isLittleEndian && !
V2->hasOneUse() && V1->
hasOneUse()) ||
10619 (isLittleEndian && !V1->
hasOneUse() &&
V2->hasOneUse())) {
10621 NeedSwap = !NeedSwap;
10656 unsigned SrcElt = PermMask[i] < 0 ? 0 : PermMask[i];
10658 if (V1HasXXSWAPD) {
10661 else if (SrcElt < 16)
10664 if (V2HasXXSWAPD) {
10667 else if (SrcElt > 15)
10676 for (
unsigned j = 0;
j != BytesPerElement; ++
j)
10677 if (isLittleEndian)
10679 DAG.
getConstant(31 - (SrcElt * BytesPerElement + j), dl, MVT::i32));
10682 DAG.
getConstant(SrcElt * BytesPerElement + j, dl, MVT::i32));
10685 if (V1HasXXSWAPD) {
10689 if (V2HasXXSWAPD) {
10690 dl =
SDLoc(
V2->getOperand(0));
10691 V2 =
V2->getOperand(0)->getOperand(1);
10694 if (isPPC64 && (V1HasXXSWAPD || V2HasXXSWAPD)) {
10695 if (ValType != MVT::v2f64)
10697 if (
V2.getValueType() != MVT::v2f64)
10701 ShufflesHandledWithVPERM++;
10706 dbgs() <<
"Emitting a XXPERM for the following shuffle:\n";
10708 dbgs() <<
"Emitting a VPERM for the following shuffle:\n";
10711 dbgs() <<
"With the following permute control vector:\n";
10716 VPermMask = DAG.
getBitcast(MVT::v4i32, VPermMask);
10720 if (isLittleEndian)
10726 VPERMNode = DAG.
getBitcast(ValType, VPERMNode);
10738 switch (IntrinsicID) {
10742 case Intrinsic::ppc_altivec_vcmpbfp_p:
10746 case Intrinsic::ppc_altivec_vcmpeqfp_p:
10750 case Intrinsic::ppc_altivec_vcmpequb_p:
10754 case Intrinsic::ppc_altivec_vcmpequh_p:
10758 case Intrinsic::ppc_altivec_vcmpequw_p:
10762 case Intrinsic::ppc_altivec_vcmpequd_p:
10763 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10769 case Intrinsic::ppc_altivec_vcmpneb_p:
10770 case Intrinsic::ppc_altivec_vcmpneh_p:
10771 case Intrinsic::ppc_altivec_vcmpnew_p:
10772 case Intrinsic::ppc_altivec_vcmpnezb_p:
10773 case Intrinsic::ppc_altivec_vcmpnezh_p:
10774 case Intrinsic::ppc_altivec_vcmpnezw_p:
10775 if (Subtarget.hasP9Altivec()) {
10776 switch (IntrinsicID) {
10779 case Intrinsic::ppc_altivec_vcmpneb_p:
10782 case Intrinsic::ppc_altivec_vcmpneh_p:
10785 case Intrinsic::ppc_altivec_vcmpnew_p:
10788 case Intrinsic::ppc_altivec_vcmpnezb_p:
10791 case Intrinsic::ppc_altivec_vcmpnezh_p:
10794 case Intrinsic::ppc_altivec_vcmpnezw_p:
10802 case Intrinsic::ppc_altivec_vcmpgefp_p:
10806 case Intrinsic::ppc_altivec_vcmpgtfp_p:
10810 case Intrinsic::ppc_altivec_vcmpgtsb_p:
10814 case Intrinsic::ppc_altivec_vcmpgtsh_p:
10818 case Intrinsic::ppc_altivec_vcmpgtsw_p:
10822 case Intrinsic::ppc_altivec_vcmpgtsd_p:
10823 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10829 case Intrinsic::ppc_altivec_vcmpgtub_p:
10833 case Intrinsic::ppc_altivec_vcmpgtuh_p:
10837 case Intrinsic::ppc_altivec_vcmpgtuw_p:
10841 case Intrinsic::ppc_altivec_vcmpgtud_p:
10842 if (Subtarget.hasVSX() || Subtarget.hasP8Altivec()) {
10849 case Intrinsic::ppc_altivec_vcmpequq:
10850 case Intrinsic::ppc_altivec_vcmpgtsq:
10851 case Intrinsic::ppc_altivec_vcmpgtuq:
10852 if (!Subtarget.isISA3_1())
10854 switch (IntrinsicID) {
10857 case Intrinsic::ppc_altivec_vcmpequq:
10860 case Intrinsic::ppc_altivec_vcmpgtsq:
10863 case Intrinsic::ppc_altivec_vcmpgtuq:
10870 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10871 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10872 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10873 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10874 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10875 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10876 if (Subtarget.hasVSX()) {
10877 switch (IntrinsicID) {
10878 case Intrinsic::ppc_vsx_xvcmpeqdp_p:
10881 case Intrinsic::ppc_vsx_xvcmpgedp_p:
10884 case Intrinsic::ppc_vsx_xvcmpgtdp_p:
10887 case Intrinsic::ppc_vsx_xvcmpeqsp_p:
10890 case Intrinsic::ppc_vsx_xvcmpgesp_p:
10893 case Intrinsic::ppc_vsx_xvcmpgtsp_p:
10903 case Intrinsic::ppc_altivec_vcmpbfp:
10906 case Intrinsic::ppc_altivec_vcmpeqfp:
10909 case Intrinsic::ppc_altivec_vcmpequb:
10912 case Intrinsic::ppc_altivec_vcmpequh:
10915 case Intrinsic::ppc_altivec_vcmpequw:
10918 case Intrinsic::ppc_altivec_vcmpequd:
10919 if (Subtarget.hasP8Altivec())
10924 case Intrinsic::ppc_altivec_vcmpneb:
10925 case Intrinsic::ppc_altivec_vcmpneh:
10926 case Intrinsic::ppc_altivec_vcmpnew:
10927 case Intrinsic::ppc_altivec_vcmpnezb:
10928 case Intrinsic::ppc_altivec_vcmpnezh:
10929 case Intrinsic::ppc_altivec_vcmpnezw:
10930 if (Subtarget.hasP9Altivec())
10931 switch (IntrinsicID) {
10934 case Intrinsic::ppc_altivec_vcmpneb:
10937 case Intrinsic::ppc_altivec_vcmpneh:
10940 case Intrinsic::ppc_altivec_vcmpnew:
10943 case Intrinsic::ppc_altivec_vcmpnezb:
10946 case Intrinsic::ppc_altivec_vcmpnezh:
10949 case Intrinsic::ppc_altivec_vcmpnezw:
10956 case Intrinsic::ppc_altivec_vcmpgefp:
10959 case Intrinsic::ppc_altivec_vcmpgtfp:
10962 case Intrinsic::ppc_altivec_vcmpgtsb:
10965 case Intrinsic::ppc_altivec_vcmpgtsh:
10968 case Intrinsic::ppc_altivec_vcmpgtsw:
10971 case Intrinsic::ppc_altivec_vcmpgtsd:
10972 if (Subtarget.hasP8Altivec())
10977 case Intrinsic::ppc_altivec_vcmpgtub:
10980 case Intrinsic::ppc_altivec_vcmpgtuh:
10983 case Intrinsic::ppc_altivec_vcmpgtuw:
10986 case Intrinsic::ppc_altivec_vcmpgtud:
10987 if (Subtarget.hasP8Altivec())
10992 case Intrinsic::ppc_altivec_vcmpequq_p:
10993 case Intrinsic::ppc_altivec_vcmpgtsq_p:
10994 case Intrinsic::ppc_altivec_vcmpgtuq_p:
10995 if (!Subtarget.isISA3_1())
10997 switch (IntrinsicID) {
11000 case Intrinsic::ppc_altivec_vcmpequq_p:
11003 case Intrinsic::ppc_altivec_vcmpgtsq_p:
11006 case Intrinsic::ppc_altivec_vcmpgtuq_p:
11020 unsigned IntrinsicID =
Op.getConstantOperandVal(0);
11024 switch (IntrinsicID) {
11025 case Intrinsic::thread_pointer:
11031 case Intrinsic::ppc_rldimi: {
11032 assert(Subtarget.
isPPC64() &&
"rldimi is only available in 64-bit!");
11036 return Op.getOperand(2);
11037 if (
Mask.isAllOnes())
11040 unsigned MB = 0, ME = 0;
11044 if (ME < 63 - SH) {
11047 }
else if (ME > 63 - SH) {
11053 {Op.getOperand(2), Src,
11054 DAG.getTargetConstant(63 - ME, dl, MVT::i32),
11055 DAG.getTargetConstant(MB, dl, MVT::i32)}),
11059 case Intrinsic::ppc_rlwimi: {
11062 return Op.getOperand(2);
11063 if (
Mask.isAllOnes())
11066 unsigned MB = 0, ME = 0;
11070 PPC::RLWIMI, dl, MVT::i32,
11071 {Op.getOperand(2), Op.getOperand(1), Op.getOperand(3),
11072 DAG.getTargetConstant(MB, dl, MVT::i32),
11073 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11077 case Intrinsic::ppc_rlwnm: {
11078 if (
Op.getConstantOperandVal(3) == 0)
11080 unsigned MB = 0, ME = 0;
11085 {Op.getOperand(1), Op.getOperand(2),
11086 DAG.getTargetConstant(MB, dl, MVT::i32),
11087 DAG.getTargetConstant(ME, dl, MVT::i32)}),
11091 case Intrinsic::ppc_mma_disassemble_acc: {
11092 if (Subtarget.isISAFuture()) {
11093 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11131 case Intrinsic::ppc_vsx_disassemble_pair: {
11134 if (IntrinsicID == Intrinsic::ppc_mma_disassemble_acc) {
11139 for (
int VecNo = 0; VecNo < NumVecs; VecNo++) {
11150 case Intrinsic::ppc_mma_xxmfacc:
11151 case Intrinsic::ppc_mma_xxmtacc: {
11153 if (!Subtarget.isISAFuture())
11164 case Intrinsic::ppc_unpack_longdouble: {
11165 auto *
Idx = dyn_cast<ConstantSDNode>(
Op.getOperand(2));
11166 assert(
Idx && (
Idx->getSExtValue() == 0 ||
Idx->getSExtValue() == 1) &&
11167 "Argument of long double unpack must be 0 or 1!");
11170 Idx->getValueType(0)));
11173 case Intrinsic::ppc_compare_exp_lt:
11174 case Intrinsic::ppc_compare_exp_gt:
11175 case Intrinsic::ppc_compare_exp_eq:
11176 case Intrinsic::ppc_compare_exp_uo: {
11178 switch (IntrinsicID) {
11179 case Intrinsic::ppc_compare_exp_lt:
11182 case Intrinsic::ppc_compare_exp_gt:
11185 case Intrinsic::ppc_compare_exp_eq:
11188 case Intrinsic::ppc_compare_exp_uo:
11194 PPC::SELECT_CC_I4, dl, MVT::i32,
11195 {SDValue(DAG.getMachineNode(PPC::XSCMPEXPDP, dl, MVT::i32,
11196 Op.getOperand(1), Op.getOperand(2)),
11198 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11199 DAG.getTargetConstant(Pred, dl, MVT::i32)}),
11202 case Intrinsic::ppc_test_data_class: {
11203 EVT OpVT =
Op.getOperand(1).getValueType();
11204 unsigned CmprOpc = OpVT == MVT::f128 ? PPC::XSTSTDCQP
11205 : (OpVT == MVT::f64 ? PPC::XSTSTDCDP
11209 PPC::SELECT_CC_I4, dl, MVT::i32,
11210 {SDValue(DAG.getMachineNode(CmprOpc, dl, MVT::i32, Op.getOperand(2),
11213 DAG.getConstant(1, dl, MVT::i32), DAG.getConstant(0, dl, MVT::i32),
11214 DAG.getTargetConstant(PPC::PRED_EQ, dl, MVT::i32)}),
11217 case Intrinsic::ppc_fnmsub: {
11218 EVT VT =
Op.getOperand(1).getValueType();
11219 if (!Subtarget.hasVSX() || (!Subtarget.hasFloat128() && VT == MVT::f128))
11225 Op.getOperand(2),
Op.getOperand(3));
11227 case Intrinsic::ppc_convert_f128_to_ppcf128:
11228 case Intrinsic::ppc_convert_ppcf128_to_f128: {
11229 RTLIB::Libcall LC = IntrinsicID == Intrinsic::ppc_convert_ppcf128_to_f128
11230 ? RTLIB::CONVERT_PPCF128_F128
11231 : RTLIB::CONVERT_F128_PPCF128;
11232 MakeLibCallOptions CallOptions;
11233 std::pair<SDValue, SDValue>
Result =
11234 makeLibCall(DAG, LC,
Op.getValueType(),
Op.getOperand(1), CallOptions,
11238 case Intrinsic::ppc_maxfe:
11239 case Intrinsic::ppc_maxfl:
11240 case Intrinsic::ppc_maxfs:
11241 case Intrinsic::ppc_minfe:
11242 case Intrinsic::ppc_minfl:
11243 case Intrinsic::ppc_minfs: {
11244 EVT VT =
Op.getValueType();
11247 [VT](
const SDUse &
Use) { return Use.getValueType() == VT; }) &&
11248 "ppc_[max|min]f[e|l|s] must have uniform type arguments");
11251 if (IntrinsicID == Intrinsic::ppc_minfe ||
11252 IntrinsicID == Intrinsic::ppc_minfl ||
11253 IntrinsicID == Intrinsic::ppc_minfs)
11275 Op.getOperand(1),
Op.getOperand(2),
11286 EVT VTs[] = {
Op.getOperand(2).getValueType(), MVT::Glue };
11294 switch (
Op.getConstantOperandVal(1)) {
11299 Bitx = PPC::sub_eq;
11305 Bitx = PPC::sub_eq;
11311 Bitx = PPC::sub_lt;
11317 Bitx = PPC::sub_lt;
11323 if (Subtarget.isISA3_1()) {
11328 CR6Reg, SubRegIdx, GlueOp),
11330 return DAG.
getNode(SetOp, dl, MVT::i32, CRBit);
11356 int ArgStart = isa<ConstantSDNode>(
Op.getOperand(0)) ? 0 : 1;
11358 switch (
Op.getConstantOperandVal(ArgStart)) {
11359 case Intrinsic::ppc_cfence: {
11360 assert(ArgStart == 1 &&
"llvm.ppc.cfence must carry a chain argument.");
11361 SDValue Val =
Op.getOperand(ArgStart + 1);
11363 if (Ty == MVT::i128) {
11368 unsigned Opcode = Subtarget.
isPPC64() ? PPC::CFENCE8 : PPC::CFENCE;
11371 Opcode,
DL, MVT::Other,
11393 int VectorIndex = 0;
11406 "Expecting an atomic compare-and-swap here.");
11408 auto *AtomicNode = cast<AtomicSDNode>(
Op.getNode());
11409 EVT MemVT = AtomicNode->getMemoryVT();
11427 for (
int i = 0, e = AtomicNode->getNumOperands(); i <
e; i++)
11428 Ops.
push_back(AtomicNode->getOperand(i));
11440 EVT MemVT =
N->getMemoryVT();
11442 "Expect quadword atomic operations");
11444 unsigned Opc =
N->getOpcode();
11452 DAG.
getConstant(Intrinsic::ppc_atomic_load_i128, dl, MVT::i32)};
11453 for (
int I = 1, E =
N->getNumOperands();
I < E; ++
I)
11456 Ops, MemVT,
N->getMemOperand());
11463 DAG.
getNode(
ISD::OR, dl, {MVT::i128, MVT::Other}, {ValLo, ValHi});
11473 DAG.
getConstant(Intrinsic::ppc_atomic_store_i128, dl, MVT::i32)};
11483 N->getMemOperand());
11495 enum DataClassMask {
11497 DC_NEG_INF = 1 << 4,
11498 DC_POS_INF = 1 << 5,
11499 DC_NEG_ZERO = 1 << 2,
11500 DC_POS_ZERO = 1 << 3,
11501 DC_NEG_SUBNORM = 1,
11502 DC_POS_SUBNORM = 1 << 1,
11505 EVT VT =
Op.getValueType();
11507 unsigned TestOp = VT == MVT::f128 ? PPC::XSTSTDCQP
11508 : VT == MVT::f64 ? PPC::XSTSTDCDP
11519 return DAG.
getNOT(Dl, Rev, MVT::i1);
11526 TestOp, Dl, MVT::i32,
11528 DC_NEG_ZERO | DC_POS_ZERO |
11529 DC_NEG_SUBNORM | DC_POS_SUBNORM,
11535 DAG.
getMachineNode(TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11541 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1, Rev,
11546 Sign = DAG.
getNOT(Dl, Sign, MVT::i1);
11559 bool IsQuiet = Mask &
fcQNan;
11565 if (VT == MVT::f128) {
11569 QuietMask = 0x8000;
11570 }
else if (VT == MVT::f64) {
11582 QuietMask = 0x80000;
11583 }
else if (VT == MVT::f32) {
11585 QuietMask = 0x400000;
11601 unsigned NativeMask = 0;
11603 NativeMask |= DC_NAN;
11605 NativeMask |= DC_NEG_INF;
11607 NativeMask |= DC_POS_INF;
11609 NativeMask |= DC_NEG_ZERO;
11611 NativeMask |= DC_POS_ZERO;
11613 NativeMask |= DC_NEG_SUBNORM;
11615 NativeMask |= DC_POS_SUBNORM;
11618 TargetOpcode::EXTRACT_SUBREG, Dl, MVT::i1,
11620 TestOp, Dl, MVT::i32,
11629 assert(Subtarget.hasP9Vector() &&
"Test data class requires Power9");
11631 uint64_t RHSC =
Op.getConstantOperandVal(1);
11634 if (
LHS.getValueType() == MVT::ppcf128) {
11650 unsigned EltSize =
Op.getValueType().getScalarSizeInBits();
11651 if (isa<ConstantSDNode>(Op0) && EltSize <= 32) {
11652 int64_t
IntVal =
Op.getConstantOperandVal(0);
11653 if (IntVal >= -16 && IntVal <= 15)
11659 if (Subtarget.hasLFIWAX() && Subtarget.hasVSX() &&
11666 RLI.Alignment, RLI.AAInfo, RLI.Ranges);
11671 spliceIntoChain(RLI.ResChain,
Bits.getValue(1), DAG);
11672 return Bits.getValue(0);
11693 64 -
Op.getValueType().getScalarSizeInBits(), dl, ShiftAmountTy);
11700 return DAG.
getLoad(
Op.getValueType(), dl, Store, FIdx,
11714 "Should only be called for ISD::INSERT_VECTOR_ELT");
11718 EVT VT =
Op.getValueType();
11723 if (VT == MVT::v2f64 &&
C)
11726 if (Subtarget.hasP9Vector()) {
11735 if ((VT == MVT::v4f32) && (
V2.getValueType() == MVT::f32) &&
11736 (isa<LoadSDNode>(V2))) {
11741 BitcastLoad,
Op.getOperand(2));
11742 return DAG.
getBitcast(MVT::v4f32, InsVecElt);
11746 if (Subtarget.isISA3_1()) {
11747 if ((VT == MVT::v2i64 || VT == MVT::v2f64) && !Subtarget.
isPPC64())
11751 if (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
11752 VT == MVT::v2i64 || VT == MVT::v4f32 || VT == MVT::v2f64)
11762 if (VT == MVT::v8i16 || VT == MVT::v16i8) {
11765 unsigned InsertAtElement =
C->getZExtValue();
11766 unsigned InsertAtByte = InsertAtElement * BytesInEachElement;
11768 InsertAtByte = (16 - BytesInEachElement) - InsertAtByte;
11782 EVT VT =
Op.getValueType();
11784 if (VT != MVT::v256i1 && VT != MVT::v512i1)
11790 assert((VT != MVT::v512i1 || Subtarget.hasMMA()) &&
11791 "Type unsupported without MMA");
11792 assert((VT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11793 "Type unsupported without paired vector support");
11798 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11800 DAG.
getLoad(MVT::v16i8, dl, LoadChain, BasePtr,
11810 std::reverse(Loads.
begin(), Loads.
end());
11811 std::reverse(LoadChains.
begin(), LoadChains.
end());
11829 EVT StoreVT =
Value.getValueType();
11831 if (StoreVT != MVT::v256i1 && StoreVT != MVT::v512i1)
11837 assert((StoreVT != MVT::v512i1 || Subtarget.hasMMA()) &&
11838 "Type unsupported without MMA");
11839 assert((StoreVT != MVT::v256i1 || Subtarget.pairedVectorMemops()) &&
11840 "Type unsupported without paired vector support");
11843 unsigned NumVecs = 2;
11844 if (StoreVT == MVT::v512i1) {
11845 if (Subtarget.isISAFuture()) {
11846 EVT ReturnTypes[] = {MVT::v256i1, MVT::v256i1};
11848 PPC::DMXXEXTFDMR512, dl, ReturnTypes,
Op.getOperand(1));
11851 Value2 =
SDValue(ExtNode, 1);
11856 for (
unsigned Idx = 0;
Idx < NumVecs; ++
Idx) {
11859 if (Subtarget.isISAFuture()) {
11869 DAG.
getStore(StoreChain, dl, Elt, BasePtr,
11883 if (
Op.getValueType() == MVT::v4i32) {
11900 LHS, RHS, DAG, dl, MVT::v4i32);
11903 LHS, RHSSwap, Zero, DAG, dl, MVT::v4i32);
11908 }
else if (
Op.getValueType() == MVT::v16i8) {
11914 LHS, RHS, DAG, dl, MVT::v8i16);
11919 LHS, RHS, DAG, dl, MVT::v8i16);
11927 for (
unsigned i = 0; i != 8; ++i) {
11928 if (isLittleEndian) {
11930 Ops[i*2+1] = 2*i+16;
11933 Ops[i*2+1] = 2*i+1+16;
11936 if (isLittleEndian)
11946 bool IsStrict =
Op->isStrictFPOpcode();
11947 if (
Op.getOperand(IsStrict ? 1 : 0).getValueType() == MVT::f128 &&
11948 !Subtarget.hasP9Vector())
11958 "Should only be called for ISD::FP_EXTEND");
11962 if (
Op.getValueType() != MVT::v2f64 ||
11963 Op.getOperand(0).getValueType() != MVT::v2f32)
11975 "Node should have 2 operands with second one being a constant!");
11987 int DWord =
Idx >> 1;
12010 LD->getMemoryVT(),
LD->getMemOperand());
12023 LD->getMemoryVT(),
LD->getMemOperand());
12038 for (
unsigned i = 0, ie =
U->getNumOperands(); i != ie; ++i) {
12039 if (
U->getOperand(i).getOpcode() !=
ISD::UADDO &&
12053 EVT VT =
Op.getNode()->getValueType(0);
12075 EVT VT =
Op.getNode()->getValueType(0);
12097 switch (
Op.getOpcode()) {
12117 return LowerSSUBO(
Op, DAG);
12129 return LowerGET_DYNAMIC_AREA_OFFSET(
Op, DAG);
12150 return LowerSET_ROUNDING(
Op, DAG);
12157 case ISD::FSHL:
return LowerFunnelShift(
Op, DAG);
12158 case ISD::FSHR:
return LowerFunnelShift(
Op, DAG);
12170 return LowerFP_ROUND(
Op, DAG);
12183 return LowerINTRINSIC_VOID(
Op, DAG);
12185 return LowerBSWAP(
Op, DAG);
12187 return LowerATOMIC_CMP_SWAP(
Op, DAG);
12189 return LowerATOMIC_LOAD_STORE(
Op, DAG);
12191 return LowerIS_FPCLASS(
Op, DAG);
12199 switch (
N->getOpcode()) {
12201 llvm_unreachable(
"Do not know how to custom type legalize this operation!");
12218 if (
N->getConstantOperandVal(1) != Intrinsic::loop_decrement)
12221 assert(
N->getValueType(0) == MVT::i1 &&
12222 "Unexpected result type for CTR decrement intrinsic");
12224 N->getValueType(0));
12234 switch (
N->getConstantOperandVal(0)) {
12235 case Intrinsic::ppc_pack_longdouble:
12237 N->getOperand(2),
N->getOperand(1)));
12239 case Intrinsic::ppc_maxfe:
12240 case Intrinsic::ppc_minfe:
12241 case Intrinsic::ppc_fnmsub:
12242 case Intrinsic::ppc_convert_f128_to_ppcf128:
12252 EVT VT =
N->getValueType(0);
12254 if (VT == MVT::i64) {
12267 if (
N->getOperand(
N->isStrictFPOpcode() ? 1 : 0).getValueType() ==
12271 Results.push_back(LoweredValue);
12272 if (
N->isStrictFPOpcode())
12277 if (!
N->getValueType(0).isVector())
12332 if (isa<LoadInst>(Inst))
12343 unsigned AtomicSize,
12344 unsigned BinOpcode,
12345 unsigned CmpOpcode,
12346 unsigned CmpPred)
const {
12350 auto LoadMnemonic = PPC::LDARX;
12351 auto StoreMnemonic = PPC::STDCX;
12352 switch (AtomicSize) {
12356 LoadMnemonic = PPC::LBARX;
12357 StoreMnemonic = PPC::STBCX;
12358 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12361 LoadMnemonic = PPC::LHARX;
12362 StoreMnemonic = PPC::STHCX;
12363 assert(Subtarget.hasPartwordAtomics() &&
"Call this only with size >=4");
12366 LoadMnemonic = PPC::LWARX;
12367 StoreMnemonic = PPC::STWCX;
12370 LoadMnemonic = PPC::LDARX;
12371 StoreMnemonic = PPC::STDCX;
12387 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12389 F->insert(It, loopMBB);
12391 F->insert(It, loop2MBB);
12392 F->insert(It, exitMBB);
12398 Register TmpReg = (!BinOpcode) ? incr :
12400 : &PPC::GPRCRegClass);
12425 BuildMI(BB, dl,
TII->get(LoadMnemonic), dest)
12432 if (CmpOpcode == PPC::CMPW && AtomicSize < 4) {
12434 BuildMI(BB, dl,
TII->get(AtomicSize == 1 ? PPC::EXTSB : PPC::EXTSH),
12462 switch(
MI.getOpcode()) {
12466 return TII->isSignExtended(
MI.getOperand(1).getReg(),
12467 &
MI.getMF()->getRegInfo());
12491 case PPC::EXTSB8_32_64:
12492 case PPC::EXTSB8_rec:
12493 case PPC::EXTSB_rec:
12496 case PPC::EXTSH8_32_64:
12497 case PPC::EXTSH8_rec:
12498 case PPC::EXTSH_rec:
12500 case PPC::EXTSWSLI:
12501 case PPC::EXTSWSLI_32_64:
12502 case PPC::EXTSWSLI_32_64_rec:
12503 case PPC::EXTSWSLI_rec:
12504 case PPC::EXTSW_32:
12505 case PPC::EXTSW_32_64:
12506 case PPC::EXTSW_32_64_rec:
12507 case PPC::EXTSW_rec:
12510 case PPC::SRAWI_rec:
12511 case PPC::SRAW_rec:
12520 unsigned BinOpcode,
unsigned CmpOpcode,
unsigned CmpPred)
const {
12530 bool IsSignExtended =
12533 if (CmpOpcode == PPC::CMPW && !IsSignExtended) {
12535 BuildMI(*BB,
MI, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueReg)
12536 .
addReg(
MI.getOperand(3).getReg());
12537 MI.getOperand(3).setReg(ValueReg);
12541 if (Subtarget.hasPartwordAtomics())
12549 bool is64bit = Subtarget.
isPPC64();
12551 unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
12562 CmpOpcode ?
F->CreateMachineBasicBlock(LLVM_BB) :
nullptr;
12564 F->insert(It, loopMBB);
12566 F->insert(It, loop2MBB);
12567 F->insert(It, exitMBB);
12573 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12618 if (ptrA != ZeroReg) {
12620 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
12628 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
12629 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
12632 .
addImm(is8bit ? 28 : 27);
12633 if (!isLittleEndian)
12634 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
12636 .
addImm(is8bit ? 24 : 16);
12638 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
12643 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
12653 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
12657 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
12662 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
12666 BuildMI(BB, dl,
TII->get(BinOpcode), TmpReg)
12669 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
12681 unsigned ValueReg = SReg;
12682 unsigned CmpReg = Incr2Reg;
12683 if (CmpOpcode == PPC::CMPW) {
12685 BuildMI(BB, dl,
TII->get(PPC::SRW), ValueReg)
12689 BuildMI(BB, dl,
TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg)
12691 ValueReg = ValueSReg;
12723 .
addImm(is8bit ? 24 : 16)
12744 Register DstReg =
MI.getOperand(0).getReg();
12746 assert(
TRI->isTypeLegalForClass(*RC, MVT::i32) &&
"Invalid destination!");
12747 Register mainDstReg =
MRI.createVirtualRegister(RC);
12748 Register restoreDstReg =
MRI.createVirtualRegister(RC);
12751 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12752 "Invalid Pointer Size!");
12800 Register LabelReg =
MRI.createVirtualRegister(PtrRC);
12801 Register BufReg =
MI.getOperand(1).getReg();
12816 BaseReg = Subtarget.
isPPC64() ? PPC::X1 : PPC::R1;
12818 BaseReg = Subtarget.
isPPC64() ? PPC::BP8 : PPC::BP;
12821 TII->get(Subtarget.
isPPC64() ? PPC::STD : PPC::STW))
12844 TII->get(Subtarget.
isPPC64() ? PPC::MFLR8 : PPC::MFLR), LabelReg);
12865 TII->get(PPC::PHI), DstReg)
12869 MI.eraseFromParent();
12883 assert((PVT == MVT::i64 || PVT == MVT::i32) &&
12884 "Invalid Pointer Size!");
12887 (PVT == MVT::i64) ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
12890 unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
12891 unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
12905 Register BufReg =
MI.getOperand(0).getReg();
12910 if (PVT == MVT::i64) {
12922 if (PVT == MVT::i64) {
12934 if (PVT == MVT::i64) {
12946 if (PVT == MVT::i64) {
12958 if (PVT == MVT::i64 && Subtarget.
isSVR4ABI()) {
12968 TII->get(PVT == MVT::i64 ? PPC::MTCTR8 : PPC::MTCTR)).
addReg(Tmp);
12971 MI.eraseFromParent();
12987 "Unexpected stack alignment");
12991 unsigned StackProbeSize =
12994 StackProbeSize &= ~(StackAlign - 1);
12995 return StackProbeSize ? StackProbeSize : StackAlign;
13007 const bool isPPC64 = Subtarget.
isPPC64();
13039 MF->
insert(MBBIter, TestMBB);
13040 MF->
insert(MBBIter, BlockMBB);
13041 MF->
insert(MBBIter, TailMBB);
13046 Register DstReg =
MI.getOperand(0).getReg();
13047 Register NegSizeReg =
MI.getOperand(1).getReg();
13049 Register FinalStackPtr =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13050 Register FramePointer =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13051 Register ActualNegSizeReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13057 if (!
MRI.hasOneNonDBGUse(NegSizeReg))
13059 isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_64 : PPC::PREPARE_PROBED_ALLOCA_32;
13065 ProbeOpc = isPPC64 ? PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_64
13066 : PPC::PREPARE_PROBED_ALLOCA_NEGSIZE_SAME_REG_32;
13068 .
addDef(ActualNegSizeReg)
13070 .
add(
MI.getOperand(2))
13071 .
add(
MI.getOperand(3));
13077 .
addReg(ActualNegSizeReg);
13080 int64_t NegProbeSize = -(int64_t)ProbeSize;
13081 assert(isInt<32>(NegProbeSize) &&
"Unhandled probe size!");
13082 Register ScratchReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13083 if (!isInt<16>(NegProbeSize)) {
13084 Register TempReg =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13086 .
addImm(NegProbeSize >> 16);
13090 .
addImm(NegProbeSize & 0xFFFF);
13097 Register Div =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13099 .
addReg(ActualNegSizeReg)
13101 Register Mul =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13105 Register NegMod =
MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13108 .
addReg(ActualNegSizeReg);
13117 Register CmpResult =
MRI.createVirtualRegister(&PPC::CRRCRegClass);
13118 BuildMI(TestMBB,
DL,
TII->get(isPPC64 ? PPC::CMPD : PPC::CMPW), CmpResult)
13143 MRI.createVirtualRegister(isPPC64 ? G8RC : GPRC);
13145 TII->get(isPPC64 ? PPC::DYNAREAOFFSET8 : PPC::DYNAREAOFFSET),
13146 MaxCallFrameSizeReg)
13147 .
add(
MI.getOperand(2))
13148 .
add(
MI.getOperand(3));
13149 BuildMI(TailMBB,
DL,
TII->get(isPPC64 ? PPC::ADD8 : PPC::ADD4), DstReg)
13151 .
addReg(MaxCallFrameSizeReg);
13160 MI.eraseFromParent();
13162 ++NumDynamicAllocaProbed;
13167 switch (
MI.getOpcode()) {
13168 case PPC::SELECT_CC_I4:
13169 case PPC::SELECT_CC_I8:
13170 case PPC::SELECT_CC_F4:
13171 case PPC::SELECT_CC_F8:
13172 case PPC::SELECT_CC_F16:
13173 case PPC::SELECT_CC_VRRC:
13174 case PPC::SELECT_CC_VSFRC:
13175 case PPC::SELECT_CC_VSSRC:
13176 case PPC::SELECT_CC_VSRC:
13177 case PPC::SELECT_CC_SPE4:
13178 case PPC::SELECT_CC_SPE:
13186 switch (
MI.getOpcode()) {
13187 case PPC::SELECT_I4:
13188 case PPC::SELECT_I8:
13189 case PPC::SELECT_F4:
13190 case PPC::SELECT_F8:
13191 case PPC::SELECT_F16:
13192 case PPC::SELECT_SPE:
13193 case PPC::SELECT_SPE4:
13194 case PPC::SELECT_VRRC:
13195 case PPC::SELECT_VSFRC:
13196 case PPC::SELECT_VSSRC:
13197 case PPC::SELECT_VSRC:
13207 if (
MI.getOpcode() == TargetOpcode::STACKMAP ||
13208 MI.getOpcode() == TargetOpcode::PATCHPOINT) {
13210 MI.getOpcode() == TargetOpcode::PATCHPOINT &&
13223 if (
MI.getOpcode() == PPC::EH_SjLj_SetJmp32 ||
13224 MI.getOpcode() == PPC::EH_SjLj_SetJmp64) {
13226 }
else if (
MI.getOpcode() == PPC::EH_SjLj_LongJmp32 ||
13227 MI.getOpcode() == PPC::EH_SjLj_LongJmp64) {
13241 if (Subtarget.hasISEL() &&
13242 (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13243 MI.getOpcode() == PPC::SELECT_CC_I8 ||
13244 MI.getOpcode() == PPC::SELECT_I4 ||
MI.getOpcode() == PPC::SELECT_I8)) {
13246 if (
MI.getOpcode() == PPC::SELECT_CC_I4 ||
13247 MI.getOpcode() == PPC::SELECT_CC_I8)
13248 Cond.push_back(
MI.getOperand(4));
13251 Cond.push_back(
MI.getOperand(1));
13254 TII->insertSelect(*BB,
MI, dl,
MI.getOperand(0).getReg(),
Cond,
13255 MI.getOperand(2).getReg(),
MI.getOperand(3).getReg());
13271 F->insert(It, copy0MBB);
13272 F->insert(It, sinkMBB);
13276 unsigned CallFrameSize =
TII->getCallFrameSizeAt(
MI);
13291 .
addReg(
MI.getOperand(1).getReg())
13294 unsigned SelectPred =
MI.getOperand(4).getImm();
13297 .
addReg(
MI.getOperand(1).getReg())
13314 .
addReg(
MI.getOperand(3).getReg())
13316 .
addReg(
MI.getOperand(2).getReg())
13318 }
else if (
MI.getOpcode() == PPC::ReadTB) {
13334 F->insert(It, readMBB);
13335 F->insert(It, sinkMBB);
13356 BuildMI(BB, dl,
TII->get(PPC::CMPW), CmpReg)
13366 }
else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I8)
13368 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I16)
13370 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I32)
13372 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_ADD_I64)
13375 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I8)
13377 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I16)
13379 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I32)
13381 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_AND_I64)
13384 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I8)
13386 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I16)
13388 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I32)
13390 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_OR_I64)
13393 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I8)
13395 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I16)
13397 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I32)
13399 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_XOR_I64)
13402 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I8)
13404 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I16)
13406 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I32)
13408 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_NAND_I64)
13411 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I8)
13413 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I16)
13415 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I32)
13417 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_SUB_I64)
13420 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I8)
13422 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I16)
13424 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I32)
13426 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MIN_I64)
13429 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I8)
13431 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I16)
13433 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I32)
13435 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_MAX_I64)
13438 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I8)
13440 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I16)
13442 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I32)
13444 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMIN_I64)
13447 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I8)
13449 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I16)
13451 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I32)
13453 else if (
MI.getOpcode() == PPC::ATOMIC_LOAD_UMAX_I64)
13456 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I8)
13458 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I16)
13460 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I32)
13462 else if (
MI.getOpcode() == PPC::ATOMIC_SWAP_I64)
13464 else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I32 ||
13465 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64 ||
13466 (Subtarget.hasPartwordAtomics() &&
13467 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8) ||
13468 (Subtarget.hasPartwordAtomics() &&
13469 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16)) {
13470 bool is64bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I64;
13472 auto LoadMnemonic = PPC::LDARX;
13473 auto StoreMnemonic = PPC::STDCX;
13474 switch (
MI.getOpcode()) {
13477 case PPC::ATOMIC_CMP_SWAP_I8:
13478 LoadMnemonic = PPC::LBARX;
13479 StoreMnemonic = PPC::STBCX;
13480 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13482 case PPC::ATOMIC_CMP_SWAP_I16:
13483 LoadMnemonic = PPC::LHARX;
13484 StoreMnemonic = PPC::STHCX;
13485 assert(Subtarget.hasPartwordAtomics() &&
"No support partword atomics.");
13487 case PPC::ATOMIC_CMP_SWAP_I32:
13488 LoadMnemonic = PPC::LWARX;
13489 StoreMnemonic = PPC::STWCX;
13491 case PPC::ATOMIC_CMP_SWAP_I64:
13492 LoadMnemonic = PPC::LDARX;
13493 StoreMnemonic = PPC::STDCX;
13501 Register oldval =
MI.getOperand(3).getReg();
13502 Register newval =
MI.getOperand(4).getReg();
13508 F->insert(It, loop1MBB);
13509 F->insert(It, loop2MBB);
13510 F->insert(It, exitMBB);
13531 BuildMI(BB, dl,
TII->get(is64bit ? PPC::CMPD : PPC::CMPW), CrReg)
13557 }
else if (
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8 ||
13558 MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I16) {
13562 bool is64bit = Subtarget.
isPPC64();
13564 bool is8bit =
MI.getOpcode() == PPC::ATOMIC_CMP_SWAP_I8;
13569 Register oldval =
MI.getOperand(3).getReg();
13570 Register newval =
MI.getOperand(4).getReg();
13576 F->insert(It, loop1MBB);
13577 F->insert(It, loop2MBB);
13578 F->insert(It, exitMBB);
13585 is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass;
13604 Register ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO;
13636 if (ptrA != ZeroReg) {
13638 BuildMI(BB, dl,
TII->get(is64bit ? PPC::ADD8 : PPC::ADD4), Ptr1Reg)
13647 BuildMI(BB, dl,
TII->get(PPC::RLWINM), Shift1Reg)
13648 .
addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0)
13651 .
addImm(is8bit ? 28 : 27);
13652 if (!isLittleEndian)
13653 BuildMI(BB, dl,
TII->get(PPC::XORI), ShiftReg)
13655 .
addImm(is8bit ? 24 : 16);
13657 BuildMI(BB, dl,
TII->get(PPC::RLDICR), PtrReg)
13662 BuildMI(BB, dl,
TII->get(PPC::RLWINM), PtrReg)
13667 BuildMI(BB, dl,
TII->get(PPC::SLW), NewVal2Reg)
13670 BuildMI(BB, dl,
TII->get(PPC::SLW), OldVal2Reg)
13677 BuildMI(BB, dl,
TII->get(PPC::ORI), Mask2Reg)
13681 BuildMI(BB, dl,
TII->get(PPC::SLW), MaskReg)
13684 BuildMI(BB, dl,
TII->get(PPC::AND), NewVal3Reg)
13687 BuildMI(BB, dl,
TII->get(PPC::AND), OldVal3Reg)
13692 BuildMI(BB, dl,
TII->get(PPC::LWARX), TmpDestReg)
13709 BuildMI(BB, dl,
TII->get(PPC::ANDC), Tmp2Reg)
13733 }
else if (
MI.getOpcode() == PPC::FADDrtz) {
13758 auto MIB =
BuildMI(*BB,
MI, dl,
TII->get(PPC::FADD), Dest)
13766 }
else if (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13767 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT ||
13768 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13769 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8) {
13770 unsigned Opcode = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8 ||
13771 MI.getOpcode() == PPC::ANDI_rec_1_GT_BIT8)
13774 bool IsEQ = (
MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT ||
13775 MI.getOpcode() == PPC::ANDI_rec_1_EQ_BIT8);
13779 Opcode == PPC::ANDI_rec ? &PPC::GPRCRegClass : &PPC::G8RCRegClass);
13783 .
addReg(
MI.getOperand(1).getReg())
13786 MI.getOperand(0).getReg())
13787 .
addReg(IsEQ ? PPC::CR0EQ : PPC::CR0GT);
13788 }
else if (
MI.getOpcode() == PPC::TCHECK_RET) {
13794 MI.getOperand(0).getReg())
13796 }
else if (
MI.getOpcode() == PPC::TBEGIN_RET) {
13798 unsigned Imm =
MI.getOperand(1).getImm();
13801 MI.getOperand(0).getReg())
13803 }
else if (
MI.getOpcode() == PPC::SETRNDi) {
13805 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13808 if (
MRI.use_empty(OldFPSCRReg))
13809 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13811 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13822 unsigned Mode =
MI.getOperand(1).getImm();
13823 BuildMI(*BB,
MI, dl,
TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
13827 BuildMI(*BB,
MI, dl,
TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
13830 }
else if (
MI.getOpcode() == PPC::SETRND) {
13838 auto copyRegFromG8RCOrF8RC = [&] (
unsigned DestReg,
unsigned SrcReg) {
13839 if (Subtarget.hasDirectMove()) {
13840 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::COPY), DestReg)
13844 unsigned StoreOp = PPC::STD, LoadOp = PPC::LFD;
13847 if (RC == &PPC::F8RCRegClass) {
13850 "Unsupported RegClass.");
13852 StoreOp = PPC::STFD;
13857 (RegInfo.
getRegClass(DestReg) == &PPC::F8RCRegClass) &&
13858 "Unsupported RegClass.");
13891 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13894 BuildMI(*BB,
MI, dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13908 copyRegFromG8RCOrF8RC(OldFPSCRTmpReg, OldFPSCRReg);
13916 BuildMI(*BB,
MI, dl,
TII->get(TargetOpcode::IMPLICIT_DEF), ImDefReg);
13917 BuildMI(*BB,
MI, dl,
TII->get(PPC::INSERT_SUBREG), ExtSrcReg)
13923 BuildMI(*BB,
MI, dl,
TII->get(PPC::RLDIMI), NewFPSCRTmpReg)
13930 copyRegFromG8RCOrF8RC(NewFPSCRReg, NewFPSCRTmpReg);
13939 }
else if (
MI.getOpcode() == PPC::SETFLM) {
13943 Register OldFPSCRReg =
MI.getOperand(0).getReg();
13944 if (
MRI.use_empty(OldFPSCRReg))
13945 BuildMI(*BB,
MI, Dl,
TII->get(TargetOpcode::IMPLICIT_DEF), OldFPSCRReg);
13947 BuildMI(*BB,
MI, Dl,
TII->get(PPC::MFFS), OldFPSCRReg);
13950 Register NewFPSCRReg =
MI.getOperand(1).getReg();
13956 }
else if (
MI.getOpcode() == PPC::PROBED_ALLOCA_32 ||
13957 MI.getOpcode() == PPC::PROBED_ALLOCA_64) {
13959 }
else if (
MI.getOpcode() == PPC::SPLIT_QUADWORD) {
13966 .
addUse(Src, 0, PPC::sub_gp8_x1);
13969 .
addUse(Src, 0, PPC::sub_gp8_x0);
13970 }
else if (
MI.getOpcode() == PPC::LQX_PSEUDO ||
13971 MI.getOpcode() == PPC::STQX_PSEUDO) {
13977 F->getRegInfo().createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);
13983 MI.getOpcode() == PPC::LQX_PSEUDO ?
TII->get(PPC::LQ)
13984 :
TII->get(PPC::STQ))
13992 MI.eraseFromParent();
14005 int RefinementSteps = Subtarget.hasRecipPrec() ? 1 : 3;
14008 return RefinementSteps;
14014 EVT VT =
Op.getValueType();
14017 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX())))
14041PPCTargetLowering::getSqrtResultForDenormInput(
SDValue Op,
14044 EVT VT =
Op.getValueType();
14045 if (VT != MVT::f64 &&
14046 ((VT != MVT::v2f64 && VT != MVT::v4f32) || !Subtarget.hasVSX()))
14053 int Enabled,
int &RefinementSteps,
14054 bool &UseOneConstNR,
14055 bool Reciprocal)
const {
14057 if ((VT == MVT::f32 && Subtarget.hasFRSQRTES()) ||
14058 (VT == MVT::f64 && Subtarget.hasFRSQRTE()) ||
14059 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14060 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14066 UseOneConstNR = !Subtarget.needsTwoConstNR();
14074 int &RefinementSteps)
const {
14076 if ((VT == MVT::f32 && Subtarget.hasFRES()) ||
14077 (VT == MVT::f64 && Subtarget.hasFRE()) ||
14078 (VT == MVT::v4f32 && Subtarget.hasAltivec()) ||
14079 (VT == MVT::v2f64 && Subtarget.hasVSX())) {
14087unsigned PPCTargetLowering::combineRepeatedFPDivisors()
const {
14125 unsigned Bytes,
int Dist,
14135 int FI = cast<FrameIndexSDNode>(Loc)->getIndex();
14136 int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
14139 if (FS != BFS || FS != (
int)Bytes)
return false;
14143 SDValue Base1 = Loc, Base2 = BaseLoc;
14144 int64_t Offset1 = 0, Offset2 = 0;
14147 if (Base1 == Base2 && Offset1 == (Offset2 + Dist * Bytes))
14157 if (isGA1 && isGA2 && GV1 == GV2)
14158 return Offset1 == (Offset2 + Dist*Bytes);
14165 unsigned Bytes,
int Dist,
14168 EVT VT = LS->getMemoryVT();
14169 SDValue Loc = LS->getBasePtr();
14175 switch (
N->getConstantOperandVal(1)) {
14176 default:
return false;
14177 case Intrinsic::ppc_altivec_lvx:
14178 case Intrinsic::ppc_altivec_lvxl:
14179 case Intrinsic::ppc_vsx_lxvw4x:
14180 case Intrinsic::ppc_vsx_lxvw4x_be:
14183 case Intrinsic::ppc_vsx_lxvd2x:
14184 case Intrinsic::ppc_vsx_lxvd2x_be:
14187 case Intrinsic::ppc_altivec_lvebx:
14190 case Intrinsic::ppc_altivec_lvehx:
14193 case Intrinsic::ppc_altivec_lvewx:
14203 switch (
N->getConstantOperandVal(1)) {
14204 default:
return false;
14205 case Intrinsic::ppc_altivec_stvx:
14206 case Intrinsic::ppc_altivec_stvxl:
14207 case Intrinsic::ppc_vsx_stxvw4x:
14210 case Intrinsic::ppc_vsx_stxvd2x:
14213 case Intrinsic::ppc_vsx_stxvw4x_be:
14216 case Intrinsic::ppc_vsx_stxvd2x_be:
14219 case Intrinsic::ppc_altivec_stvebx:
14222 case Intrinsic::ppc_altivec_stvehx:
14225 case Intrinsic::ppc_altivec_stvewx:
14242 SDValue Chain = LD->getChain();
14243 EVT VT = LD->getMemoryVT();
14252 while (!Queue.empty()) {
14253 SDNode *ChainNext = Queue.pop_back_val();
14254 if (!Visited.
insert(ChainNext).second)
14257 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(ChainNext)) {
14261 if (!Visited.
count(ChainLD->getChain().getNode()))
14262 Queue.push_back(ChainLD->getChain().getNode());
14264 for (
const SDUse &O : ChainNext->
ops())
14265 if (!Visited.
count(O.getNode()))
14266 Queue.push_back(O.getNode());
14268 LoadRoots.
insert(ChainNext);
14279 for (
SDNode *
I : LoadRoots) {
14280 Queue.push_back(
I);
14282 while (!Queue.empty()) {
14283 SDNode *LoadRoot = Queue.pop_back_val();
14284 if (!Visited.
insert(LoadRoot).second)
14287 if (
MemSDNode *ChainLD = dyn_cast<MemSDNode>(LoadRoot))
14292 if (((isa<MemSDNode>(U) &&
14293 cast<MemSDNode>(U)->getChain().
getNode() == LoadRoot) ||
14296 Queue.push_back(U);
14329 auto Final = Shifted;
14340 DAGCombinerInfo &DCI)
const {
14348 if (!DCI.isAfterLegalizeDAG())
14353 for (
const SDNode *U :
N->users())
14358 auto OpSize =
N->getOperand(0).getValueSizeInBits();
14362 if (OpSize <
Size) {
14380 DAGCombinerInfo &DCI)
const {
14384 assert(Subtarget.useCRBits() &&
"Expecting to be tracking CR bits");
14395 N->getValueType(0) != MVT::i1)
14398 if (
N->getOperand(0).getValueType() != MVT::i32 &&
14399 N->getOperand(0).getValueType() != MVT::i64)
14407 cast<CondCodeSDNode>(
N->getOperand(
14409 unsigned OpBits =
N->getOperand(0).getValueSizeInBits();
14420 return (
N->getOpcode() ==
ISD::SETCC ? ConvertSETCCToSubtract(
N, DCI)
14443 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14444 N->getOperand(0).getOpcode() !=
ISD::OR &&
14445 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14455 N->getOperand(1).getOpcode() !=
ISD::AND &&
14456 N->getOperand(1).getOpcode() !=
ISD::OR &&
14457 N->getOperand(1).getOpcode() !=
ISD::XOR &&
14470 for (
unsigned i = 0; i < 2; ++i) {
14474 N->getOperand(i).getOperand(0).getValueType() == MVT::i1) ||
14475 isa<ConstantSDNode>(
N->getOperand(i)))
14486 while (!BinOps.
empty()) {
14494 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14528 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14529 if (isa<ConstantSDNode>(Inputs[i]))
14552 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14574 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14577 if (isa<ConstantSDNode>(Inputs[i]))
14583 std::list<HandleSDNode> PromOpHandles;
14584 for (
auto &PromOp : PromOps)
14585 PromOpHandles.emplace_back(PromOp);
14592 while (!PromOpHandles.empty()) {
14594 PromOpHandles.pop_back();
14600 if (!isa<ConstantSDNode>(PromOp.
getOperand(0)) &&
14603 PromOpHandles.emplace_front(PromOp);
14608 if (isa<ConstantSDNode>(RepValue))
14617 default:
C = 0;
break;
14622 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14630 PromOpHandles.emplace_front(PromOp);
14637 for (
unsigned i = 0; i < 2; ++i)
14638 if (isa<ConstantSDNode>(Ops[
C+i]))
14647 return N->getOperand(0);
14655 DAGCombinerInfo &DCI)
const {
14673 if (
N->getValueType(0) != MVT::i32 &&
14674 N->getValueType(0) != MVT::i64)
14677 if (!((
N->getOperand(0).getValueType() == MVT::i1 && Subtarget.useCRBits()) ||
14678 (
N->getOperand(0).getValueType() == MVT::i32 && Subtarget.
isPPC64())))
14681 if (
N->getOperand(0).getOpcode() !=
ISD::AND &&
14682 N->getOperand(0).getOpcode() !=
ISD::OR &&
14683 N->getOperand(0).getOpcode() !=
ISD::XOR &&
14694 while (!BinOps.
empty()) {
14702 for (
unsigned i = 0, ie = BinOp.
getNumOperands(); i != ie; ++i) {
14733 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14734 if (isa<ConstantSDNode>(Inputs[i]))
14745 SelectTruncOp[0].
insert(std::make_pair(
User,
14749 SelectTruncOp[0].
insert(std::make_pair(
User,
14752 SelectTruncOp[1].
insert(std::make_pair(
User,
14758 for (
unsigned i = 0, ie = PromOps.
size(); i != ie; ++i) {
14767 SelectTruncOp[0].
insert(std::make_pair(
User,
14771 SelectTruncOp[0].
insert(std::make_pair(
User,
14774 SelectTruncOp[1].
insert(std::make_pair(
User,
14780 unsigned PromBits =
N->getOperand(0).getValueSizeInBits();
14781 bool ReallyNeedsExt =
false;
14785 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14786 if (isa<ConstantSDNode>(Inputs[i]))
14790 Inputs[i].getOperand(0).getValueSizeInBits();
14791 assert(PromBits < OpBits &&
"Truncation not to a smaller bit count?");
14796 OpBits-PromBits))) ||
14799 (OpBits-(PromBits-1)))) {
14800 ReallyNeedsExt =
true;
14808 for (
unsigned i = 0, ie = Inputs.
size(); i != ie; ++i) {
14812 if (isa<ConstantSDNode>(Inputs[i]))
14815 SDValue InSrc = Inputs[i].getOperand(0);
14829 std::list<HandleSDNode> PromOpHandles;
14830 for (
auto &PromOp : PromOps)
14831 PromOpHandles.emplace_back(PromOp);
14837 while (!PromOpHandles.empty()) {
14839 PromOpHandles.pop_back();
14843 default:
C = 0;
break;
14848 if ((!isa<ConstantSDNode>(PromOp.
getOperand(
C)) &&
14856 PromOpHandles.emplace_front(PromOp);
14866 (SelectTruncOp[1].count(PromOp.
getNode()) &&
14868 PromOpHandles.emplace_front(PromOp);
14877 for (
unsigned i = 0; i < 2; ++i) {
14878 if (!isa<ConstantSDNode>(Ops[
C+i]))
14895 auto SI0 = SelectTruncOp[0].
find(PromOp.
getNode());
14896 if (SI0 != SelectTruncOp[0].
end())
14898 auto SI1 = SelectTruncOp[1].
find(PromOp.
getNode());
14899 if (SI1 != SelectTruncOp[1].
end())
14908 if (!ReallyNeedsExt)
14909 return N->getOperand(0);
14916 N->getValueSizeInBits(0), PromBits),
14917 dl,
N->getValueType(0)));
14920 "Invalid extension type");
14923 DAG.
getConstant(
N->getValueSizeInBits(0) - PromBits, dl, ShiftAmountTy);
14931 DAGCombinerInfo &DCI)
const {
14933 "Should be called with a SETCC node");
14951 EVT VT =
N->getValueType(0);
14952 EVT OpVT =
LHS.getValueType();
14958 return DAGCombineTruncBoolExt(
N, DCI);
14963 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(
Op.getNode()))
14965 Op.getValueType() == MVT::f64;
14977combineElementTruncationToVectorTruncation(
SDNode *
N,
14978 DAGCombinerInfo &DCI)
const {
14980 "Should be called with a BUILD_VECTOR node");
14985 SDValue FirstInput =
N->getOperand(0);
14987 "The input operand must be an fp-to-int conversion.");
14996 bool IsSplat =
true;
15001 EVT TargetVT =
N->getValueType(0);
15002 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15003 SDValue NextOp =
N->getOperand(i);
15007 if (NextConversion != FirstConversion)
15015 if (
N->getOperand(i) != FirstInput)
15026 for (
int i = 0, e =
N->getNumOperands(); i < e; ++i) {
15027 SDValue In =
N->getOperand(i).getOperand(0);
15050 EVT NewVT = TargetVT == MVT::v2i64 ? MVT::v2f64 : MVT::v4f32;
15052 return DAG.
getNode(Opcode, dl, TargetVT, BV);
15065 "Should be called with a BUILD_VECTOR node");
15070 if (!
N->getValueType(0).getVectorElementType().isByteSized())
15073 bool InputsAreConsecutiveLoads =
true;
15074 bool InputsAreReverseConsecutive =
true;
15075 unsigned ElemSize =
N->getValueType(0).getScalarType().getStoreSize();
15076 SDValue FirstInput =
N->getOperand(0);
15077 bool IsRoundOfExtLoad =
false;
15082 FirstLoad = cast<LoadSDNode>(FirstInput.
getOperand(0));
15087 N->getNumOperands() == 1)
15090 if (!IsRoundOfExtLoad)
15091 FirstLoad = cast<LoadSDNode>(FirstInput);
15095 for (
int i = 1, e =
N->getNumOperands(); i < e; ++i) {
15097 if (IsRoundOfExtLoad &&
N->getOperand(i).getOpcode() !=
ISD::FP_ROUND)
15100 SDValue NextInput = IsRoundOfExtLoad ?
N->getOperand(i).getOperand(0) :
15106 IsRoundOfExtLoad ?
N->getOperand(i-1).getOperand(0) :
N->getOperand(i-1);
15107 LoadSDNode *LD1 = cast<LoadSDNode>(PreviousInput);
15108 LoadSDNode *LD2 = cast<LoadSDNode>(NextInput);
15117 InputsAreConsecutiveLoads =
false;
15119 InputsAreReverseConsecutive =
false;
15122 if (!InputsAreConsecutiveLoads && !InputsAreReverseConsecutive)
15127 assert(!(InputsAreConsecutiveLoads && InputsAreReverseConsecutive) &&
15128 "The loads cannot be both consecutive and reverse consecutive.");
15132 if (InputsAreConsecutiveLoads) {
15133 assert(FirstLoad &&
"Input needs to be a LoadSDNode.");
15137 ReturnSDVal = WideLoad;
15138 }
else if (InputsAreReverseConsecutive) {
15140 assert(LastLoad &&
"Input needs to be a LoadSDNode.");
15145 for (
int i =
N->getNumOperands() - 1; i >= 0; i--)
15149 DAG.
getUNDEF(
N->getValueType(0)), Ops);
15153 for (
auto *LD : InputLoads)
15155 return ReturnSDVal;
15172 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15174 ShuffleMask[CorrectElems & 0xF] = Elems & 0xF;
15176 ShuffleMask[(CorrectElems & 0xF0) >> 4] = (Elems & 0xF0) >> 4;
15177 CorrectElems = CorrectElems >> 8;
15178 Elems = Elems >> 8;
15185 EVT VT =
N->getValueType(0);
15223 auto isSExtOfVecExtract = [&](
SDValue Op) ->
bool {
15243 if (Input && Input != Extract.
getOperand(0))
15249 Elems = Elems << 8;
15258 for (
unsigned i = 0; i <
N->getNumOperands(); i++) {
15259 if (!isSExtOfVecExtract(
N->getOperand(i))) {
15266 int TgtElemArrayIdx;
15268 int OutputSize =
N->getValueType(0).getScalarSizeInBits();
15269 if (InputSize + OutputSize == 40)
15270 TgtElemArrayIdx = 0;
15271 else if (InputSize + OutputSize == 72)
15272 TgtElemArrayIdx = 1;
15273 else if (InputSize + OutputSize == 48)
15274 TgtElemArrayIdx = 2;
15275 else if (InputSize + OutputSize == 80)
15276 TgtElemArrayIdx = 3;
15277 else if (InputSize + OutputSize == 96)
15278 TgtElemArrayIdx = 4;
15282 uint64_t CorrectElems = TargetElems[TgtElemArrayIdx];
15284 ? CorrectElems & 0x0F0F0F0F0F0F0F0F
15285 : CorrectElems & 0xF0F0F0F0F0F0F0F0;
15286 if (Elems != CorrectElems) {
15302 if (
N->getValueType(0) != MVT::v1i128)
15305 SDValue Operand =
N->getOperand(0);
15311 auto *LD = cast<LoadSDNode>(Operand);
15312 EVT MemoryType = LD->getMemoryVT();
15316 bool ValidLDType = MemoryType == MVT::i8 || MemoryType == MVT::i16 ||
15317 MemoryType == MVT::i32 || MemoryType == MVT::i64;
15320 if (!ValidLDType ||
15326 LD->getChain(), LD->getBasePtr(),
15330 DAG.
getVTList(MVT::v1i128, MVT::Other),
15331 LoadOps, MemoryType, LD->getMemOperand());
15335 DAGCombinerInfo &DCI)
const {
15337 "Should be called with a BUILD_VECTOR node");
15342 if (!Subtarget.hasVSX())
15348 SDValue FirstInput =
N->getOperand(0);
15350 SDValue Reduced = combineElementTruncationToVectorTruncation(
N, DCI);
15365 if (Subtarget.hasP9Altivec() && !DCI.isBeforeLegalize()) {
15374 if (Subtarget.isISA3_1()) {
15380 if (
N->getValueType(0) != MVT::v2f64)
15391 if (FirstInput.
getOpcode() !=
N->getOperand(1).getOpcode())
15395 SDValue Ext2 =
N->getOperand(1).getOperand(0);
15402 if (!Ext1Op || !Ext2Op)
15411 if (FirstElem == 0 && SecondElem == 1)
15413 else if (FirstElem == 2 && SecondElem == 3)
15421 return DAG.
getNode(NodeType, dl, MVT::v2f64,
15426 DAGCombinerInfo &DCI)
const {
15429 "Need an int -> FP conversion node here");
15440 if (
Op.getValueType() != MVT::f32 &&
Op.getValueType() != MVT::f64)
15442 if (!
Op.getOperand(0).getValueType().isSimple())
15444 if (
Op.getOperand(0).getValueType().getSimpleVT() <=
MVT(MVT::i1) ||
15445 Op.getOperand(0).getValueType().getSimpleVT() >
MVT(MVT::i64))
15448 SDValue FirstOperand(
Op.getOperand(0));
15449 bool SubWordLoad = FirstOperand.getOpcode() ==
ISD::LOAD &&
15450 (FirstOperand.getValueType() == MVT::i8 ||
15451 FirstOperand.getValueType() == MVT::i16);
15452 if (Subtarget.hasP9Vector() && Subtarget.hasP9Altivec() && SubWordLoad) {
15454 bool DstDouble =
Op.getValueType() == MVT::f64;
15455 unsigned ConvOp =
Signed ?
15461 LoadSDNode *LDN = cast<LoadSDNode>(FirstOperand.getNode());
15470 SDValue ExtOps[] = { Ld, WidthConst };
15472 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ext);
15474 return DAG.
getNode(ConvOp, dl, DstDouble ? MVT::f64 : MVT::f32, Ld);
15482 if (
Op.getOperand(0).getValueType() == MVT::i32)
15486 "UINT_TO_FP is supported only with FPCVT");
15490 unsigned FCFOp = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15495 MVT FCFTy = (Subtarget.hasFPCVT() &&
Op.getValueType() == MVT::f32)
15502 Subtarget.hasFPCVT()) ||
15504 SDValue Src =
Op.getOperand(0).getOperand(0);
15505 if (Src.getValueType() == MVT::f32) {
15507 DCI.AddToWorklist(Src.getNode());
15508 }
else if (Src.getValueType() != MVT::f64) {
15520 if (
Op.getValueType() == MVT::f32 && !Subtarget.hasFPCVT()) {
15523 DCI.AddToWorklist(
FP.getNode());
15547 switch (
N->getOpcode()) {
15552 Chain = LD->getChain();
15553 Base = LD->getBasePtr();
15554 MMO = LD->getMemOperand();
15573 MVT VecTy =
N->getValueType(0).getSimpleVT();
15581 Chain = Load.getValue(1);
15587 if (VecTy != MVT::v2f64) {
15614 switch (
N->getOpcode()) {
15619 Chain = ST->getChain();
15620 Base = ST->getBasePtr();
15621 MMO = ST->getMemOperand();
15641 SDValue Src =
N->getOperand(SrcOpnd);
15642 MVT VecTy = Src.getValueType().getSimpleVT();
15645 if (VecTy != MVT::v2f64) {
15651 DAG.
getVTList(MVT::v2f64, MVT::Other), Chain, Src);
15657 StoreOps, VecTy, MMO);
15664 DAGCombinerInfo &DCI)
const {
15667 unsigned Opcode =
N->getOperand(1).getOpcode();
15669 bool Strict =
N->getOperand(1)->isStrictFPOpcode();
15673 &&
"Not a FP_TO_INT Instruction!");
15675 SDValue Val =
N->getOperand(1).getOperand(Strict ? 1 : 0);
15676 EVT Op1VT =
N->getOperand(1).getValueType();
15679 if (!Subtarget.hasVSX() || !Subtarget.hasFPCVT() || !
isTypeLegal(ResVT))
15683 bool ValidTypeForStoreFltAsInt =
15684 (Op1VT == MVT::i32 || (Op1VT == MVT::i64 && Subtarget.
isPPC64()) ||
15685 (Subtarget.hasP9Vector() && (Op1VT == MVT::i16 || Op1VT == MVT::i8)));
15688 if (ResVT == MVT::ppcf128 || (ResVT == MVT::f128 && !Subtarget.hasP9Vector()))
15691 if ((Op1VT != MVT::i64 && !Subtarget.hasP8Vector()) ||
15692 cast<StoreSDNode>(
N)->isTruncatingStore() || !ValidTypeForStoreFltAsInt)
15699 SDValue Ops[] = {
N->getOperand(0), Val,
N->getOperand(2),
15705 cast<StoreSDNode>(
N)->getMemoryVT(),
15706 cast<StoreSDNode>(
N)->getMemOperand());
15714 bool PrevElemFromFirstVec = Mask[0] < NumElts;
15715 for (
int i = 1, e = Mask.size(); i < e; i++) {
15716 if (PrevElemFromFirstVec && Mask[i] < NumElts)
15718 if (!PrevElemFromFirstVec && Mask[i] >= NumElts)
15720 PrevElemFromFirstVec = !PrevElemFromFirstVec;
15732 FirstOp =
Op.getOperand(i);
15739 if (
Op.getOperand(i) != FirstOp && !
Op.getOperand(i).isUndef())
15749 Op =
Op.getOperand(0);
15765 int RHSFirstElt,
int RHSLastElt,
int HalfVec,
unsigned LHSNumValidElts,
15766 unsigned RHSNumValidElts,
const PPCSubtarget &Subtarget) {
15768 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - LHSNumValidElts;
15770 Subtarget.
isLittleEndian() ? HalfVec : HalfVec - RHSNumValidElts;
15771 for (
int I = 0, E = ShuffV.
size();
I < E; ++
I) {
15772 int Idx = ShuffV[
I];
15773 if (
Idx >= LHSFirstElt &&
Idx <= LHSLastElt)
15774 ShuffV[
I] += LHSEltFixup;
15775 else if (
Idx >= RHSFirstElt &&
Idx <= RHSLastElt)
15776 ShuffV[
I] += RHSEltFixup;
15787 SDLoc dl(OrigSToV);
15790 "Expecting a SCALAR_TO_VECTOR here");
15803 "Cannot produce a permuted scalar_to_vector for one element vector");
15805 unsigned ResultInElt = NumElts / 2;
15807 NewMask[ResultInElt] =
Idx->getZExtValue();
15816 int HalfVec,
int LHSLastElementDefined,
15817 int RHSLastElementDefined) {
15818 for (
int Index : ShuffV) {
15822 if ((LHSLastElementDefined >= 0) && (Index < HalfVec) &&
15823 (Index > LHSLastElementDefined))
15826 if ((RHSLastElementDefined >= 0) &&
15827 (Index > HalfVec + RHSLastElementDefined))
15834 int ScalarSize,
uint64_t ShuffleEltWidth,
unsigned &NumValidElts,
15835 int FirstElt,
int &LastElt,
SDValue VecShuffOperand,
SDValue SToVNode,
15851 LastElt = (
uint64_t)ScalarSize > ShuffleEltWidth
15852 ? ScalarSize / ShuffleEltWidth - 1 + FirstElt
15855 if (SToVPermuted.
getValueType() != VecShuffOperandType)
15856 SToVPermuted = DAG.
getBitcast(VecShuffOperandType, SToVPermuted);
15857 return SToVPermuted;
15877 int NumElts =
LHS.getValueType().getVectorNumElements();
15887 if (!Subtarget.hasDirectMove())
15897 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15906 if (SToVLHS || SToVRHS) {
15909 int ShuffleNumElts = ShuffV.
size();
15910 int HalfVec = ShuffleNumElts / 2;
15916 unsigned LHSNumValidElts = HalfVec;
15917 unsigned RHSNumValidElts = HalfVec;
15922 int LHSFirstElt = 0;
15923 int RHSFirstElt = ShuffleNumElts;
15924 int LHSLastElt = -1;
15925 int RHSLastElt = -1;
15933 int LHSScalarSize = 0;
15934 int RHSScalarSize = 0;
15937 if (!IsLittleEndian && LHSScalarSize >= 64)
15942 if (!IsLittleEndian && RHSScalarSize >= 64)
15945 if (LHSScalarSize != 0)
15947 LHSScalarSize, ShuffleEltWidth, LHSNumValidElts, LHSFirstElt,
15948 LHSLastElt, LHS, SToVLHS, DAG, Subtarget);
15949 if (RHSScalarSize != 0)
15951 RHSScalarSize, ShuffleEltWidth, RHSNumValidElts, RHSFirstElt,
15952 RHSLastElt, RHS, SToVRHS, DAG, Subtarget);
15963 ShuffV, LHSFirstElt, LHSLastElt, RHSFirstElt, RHSLastElt, HalfVec,
15964 LHSNumValidElts, RHSNumValidElts, Subtarget);
15969 if (!isa<ShuffleVectorSDNode>(Res))
15971 Mask = cast<ShuffleVectorSDNode>(Res)->getMask();
15990 if (IsLittleEndian) {
15993 if (Mask[0] < NumElts)
15994 for (
int i = 1, e =
Mask.size(); i < e; i += 2) {
15998 ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
16003 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
16007 ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
16012 if (Mask[0] < NumElts)
16013 for (
int i = 0, e =
Mask.size(); i <
e; i += 2) {
16017 ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
16022 for (
int i = 1, e =
Mask.size(); i <
e; i += 2) {
16026 ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
16033 cast<BuildVectorSDNode>(TheSplat.
getNode())->getSplatValue();
16036 if (IsLittleEndian)
16045 DAGCombinerInfo &DCI)
const {
16047 "Not a reverse memop pattern!");
16052 auto I =
Mask.rbegin();
16053 auto E =
Mask.rend();
16055 for (;
I != E; ++
I) {
16072 if (!Subtarget.hasP9Vector())
16075 if(!IsElementReverse(SVN))
16083 if (
Use.getResNo() == 0 &&
16114 if (IntrinsicID == Intrinsic::ppc_stdcx)
16116 else if (IntrinsicID == Intrinsic::ppc_stwcx)
16118 else if (IntrinsicID == Intrinsic::ppc_sthcx)
16120 else if (IntrinsicID == Intrinsic::ppc_stbcx)
16131 switch (
N->getOpcode()) {
16134 return combineADD(
N, DCI);
16143 !isa<ConstantSDNode>(Op2) ||
N->getValueType(0) != MVT::i64 ||
16153 if (!isUInt<32>(Imm))
16160 return combineSHL(
N, DCI);
16162 return combineSRA(
N, DCI);
16164 return combineSRL(
N, DCI);
16166 return combineMUL(
N, DCI);
16169 return combineFMALike(
N, DCI);
16172 return N->getOperand(0);
16176 return N->getOperand(0);
16182 return N->getOperand(0);
16188 return DAGCombineExtBoolTrunc(
N, DCI);
16190 return combineTRUNCATE(
N, DCI);
16192 if (
SDValue CSCC = combineSetCC(
N, DCI))
16196 return DAGCombineTruncBoolExt(
N, DCI);
16199 return combineFPToIntToFP(
N, DCI);
16202 LSBaseSDNode* LSBase = cast<LSBaseSDNode>(
N->getOperand(0));
16203 return combineVReverseMemOP(cast<ShuffleVectorSDNode>(
N), LSBase, DCI);
16205 return combineVectorShuffle(cast<ShuffleVectorSDNode>(
N), DCI.
DAG);
16208 EVT Op1VT =
N->getOperand(1).getValueType();
16209 unsigned Opcode =
N->getOperand(1).getOpcode();
16213 SDValue Val = combineStoreFPToInt(
N, DCI);
16220 SDValue Val= combineVReverseMemOP(SVN, cast<LSBaseSDNode>(
N), DCI);
16226 if (cast<StoreSDNode>(
N)->isUnindexed() && Opcode ==
ISD::BSWAP &&
16227 N->getOperand(1).getNode()->hasOneUse() &&
16228 (Op1VT == MVT::i32 || Op1VT == MVT::i16 ||
16229 (Subtarget.hasLDBRX() && Subtarget.
isPPC64() && Op1VT == MVT::i64))) {
16233 EVT mVT = cast<StoreSDNode>(
N)->getMemoryVT();
16237 SDValue BSwapOp =
N->getOperand(1).getOperand(0);
16244 if (Op1VT.
bitsGT(mVT)) {
16249 if (Op1VT == MVT::i64)
16254 N->getOperand(0), BSwapOp,
N->getOperand(2), DAG.
getValueType(mVT)
16258 Ops, cast<StoreSDNode>(
N)->getMemoryVT(),
16259 cast<StoreSDNode>(
N)->getMemOperand());
16265 isa<ConstantSDNode>(
N->getOperand(1)) && Op1VT == MVT::i32) {
16267 EVT MemVT = cast<StoreSDNode>(
N)->getMemoryVT();
16277 cast<StoreSDNode>(
N)->setTruncatingStore(
true);
16286 (StoreVT == MVT::v2f64 || StoreVT == MVT::v2i64 ||
16287 StoreVT == MVT::v4f32 || StoreVT == MVT::v4i32))
16294 EVT VT = LD->getValueType(0);
16301 (LoadVT == MVT::v2f64 || LoadVT == MVT::v2i64 ||
16302 LoadVT == MVT::v4f32 || LoadVT == MVT::v4i32))
16313 auto ReplaceTwoFloatLoad = [&]() {
16314 if (VT != MVT::i64)
16329 if (!LD->hasNUsesOfValue(2, 0))
16332 auto UI = LD->user_begin();
16333 while (UI.getUse().getResNo() != 0) ++UI;
16335 while (UI.getUse().getResNo() != 0) ++UI;
16336 SDNode *RightShift = *UI;
16344 if (RightShift->getOpcode() !=
ISD::SRL ||
16345 !isa<ConstantSDNode>(RightShift->getOperand(1)) ||
16346 RightShift->getConstantOperandVal(1) != 32 ||
16347 !RightShift->hasOneUse())
16350 SDNode *Trunc2 = *RightShift->user_begin();
16360 Bitcast->getValueType(0) != MVT::f32)
16372 SDValue BasePtr = LD->getBasePtr();
16373 if (LD->isIndexed()) {
16375 "Non-pre-inc AM on PPC?");
16383 SDValue FloatLoad = DAG.
getLoad(MVT::f32, dl, LD->getChain(), BasePtr,
16384 LD->getPointerInfo(), LD->getAlign(),
16385 MMOFlags, LD->getAAInfo());
16391 LD->getPointerInfo().getWithOffset(4),
16394 if (LD->isIndexed()) {
16408 if (ReplaceTwoFloatLoad())
16411 EVT MemVT = LD->getMemoryVT();
16414 if (LD->isUnindexed() && VT.
isVector() &&
16417 !Subtarget.hasP8Vector() &&
16418 (VT == MVT::v16i8 || VT == MVT::v8i16 || VT == MVT::v4i32 ||
16419 VT == MVT::v4f32))) &&
16420 LD->getAlign() < ABIAlignment) {
16422 SDValue Chain = LD->getChain();
16451 MVT PermCntlTy, PermTy, LDTy;
16452 Intr = isLittleEndian ? Intrinsic::ppc_altivec_lvsr
16453 : Intrinsic::ppc_altivec_lvsl;
16454 IntrLD = Intrinsic::ppc_altivec_lvx;
16455 IntrPerm = Intrinsic::ppc_altivec_vperm;
16456 PermCntlTy = MVT::v16i8;
16457 PermTy = MVT::v4i32;
16476 SDValue BaseLoadOps[] = { Chain, LDXIntID,
Ptr };
16480 BaseLoadOps, LDTy, BaseMMO);
16489 int IncValue = IncOffset;
16506 SDValue ExtraLoadOps[] = { Chain, LDXIntID,
Ptr };
16510 ExtraLoadOps, LDTy, ExtraMMO);
16521 if (isLittleEndian)
16523 ExtraLoad, BaseLoad, PermCntl, DAG, dl);
16526 BaseLoad, ExtraLoad, PermCntl, DAG, dl);
16529 Perm = Subtarget.hasAltivec()
16545 unsigned IID =
N->getConstantOperandVal(0);
16547 : Intrinsic::ppc_altivec_lvsl);
16548 if (IID ==
Intr &&
N->getOperand(1)->getOpcode() ==
ISD::ADD) {
16555 .
zext(
Add.getScalarValueSizeInBits()))) {
16556 SDNode *BasePtr =
Add->getOperand(0).getNode();
16557 for (
SDNode *U : BasePtr->users()) {
16559 U->getConstantOperandVal(0) == IID) {
16569 if (isa<ConstantSDNode>(
Add->getOperand(1))) {
16570 SDNode *BasePtr =
Add->getOperand(0).getNode();
16571 for (
SDNode *U : BasePtr->users()) {
16573 isa<ConstantSDNode>(U->getOperand(1)) &&
16574 (
Add->getConstantOperandVal(1) - U->getConstantOperandVal(1)) %
16580 V->getConstantOperandVal(0) == IID) {
16592 (IID == Intrinsic::ppc_altivec_vmaxsw ||
16593 IID == Intrinsic::ppc_altivec_vmaxsh ||
16594 IID == Intrinsic::ppc_altivec_vmaxsb)) {
16610 V2.getOperand(1) == V1) {
16625 switch (
N->getConstantOperandVal(1)) {
16628 case Intrinsic::ppc_altivec_vsum4sbs:
16629 case Intrinsic::ppc_altivec_vsum4shs:
16630 case Intrinsic::ppc_altivec_vsum4ubs: {
16636 dyn_cast<BuildVectorSDNode>(
N->getOperand(3))) {
16637 APInt APSplatBits, APSplatUndef;
16638 unsigned SplatBitSize;
16641 APSplatBits, APSplatUndef, SplatBitSize, HasAnyUndefs, 0,
16644 if (BVNIsConstantSplat && APSplatBits == 0)
16649 case Intrinsic::ppc_vsx_lxvw4x:
16650 case Intrinsic::ppc_vsx_lxvd2x:
16662 switch (
N->getConstantOperandVal(1)) {
16665 case Intrinsic::ppc_vsx_stxvw4x:
16666 case Intrinsic::ppc_vsx_stxvd2x:
16675 bool Is64BitBswapOn64BitTgt =
16676 Subtarget.
isPPC64() &&
N->getValueType(0) == MVT::i64;
16678 N->getOperand(0).hasOneUse();
16679 if (IsSingleUseNormalLd &&
16680 (
N->getValueType(0) == MVT::i32 ||
N->getValueType(0) == MVT::i16 ||
16681 (Subtarget.hasLDBRX() && Is64BitBswapOn64BitTgt))) {
16692 DAG.
getVTList(
N->getValueType(0) == MVT::i64 ?
16693 MVT::i64 : MVT::i32, MVT::Other),
16694 Ops, LD->getMemoryVT(), LD->getMemOperand());
16698 if (
N->getValueType(0) == MVT::i16)
16715 !IsSingleUseNormalLd)
16717 LoadSDNode *LD = cast<LoadSDNode>(
N->getOperand(0));
16720 if (!LD->isSimple())
16722 SDValue BasePtr = LD->getBasePtr();
16724 LD->getPointerInfo(), LD->getAlign());
16729 LD->getMemOperand(), 4, 4);
16739 Hi.getOperand(0).getValue(1),
Lo.getOperand(0).getValue(1));
16748 if (!
N->getOperand(0).hasOneUse() &&
16749 !
N->getOperand(1).hasOneUse() &&
16750 !
N->getOperand(2).hasOneUse()) {
16753 SDNode *VCMPrecNode =
nullptr;
16755 SDNode *LHSN =
N->getOperand(0).getNode();
16761 VCMPrecNode =
User;
16773 SDNode *FlagUser =
nullptr;
16775 FlagUser ==
nullptr; ++UI) {
16776 assert(UI != VCMPrecNode->
use_end() &&
"Didn't find user!");
16789 return SDValue(VCMPrecNode, 0);
16811 auto RHSAPInt =
RHS->getAsAPIntVal();
16812 if (!RHSAPInt.isIntN(64))
16815 unsigned Val = RHSAPInt.getZExtValue();
16816 auto isImpossibleCompare = [&]() {
16819 if (Val != 0 && Val != 1) {
16821 return N->getOperand(0);
16824 N->getOperand(0),
N->getOperand(4));
16829 unsigned StoreWidth = 0;
16832 if (
SDValue Impossible = isImpossibleCompare())
16846 auto *MemNode = cast<MemSDNode>(
LHS);
16849 DAG.
getVTList(MVT::i32, MVT::Other, MVT::Glue), Ops,
16850 MemNode->getMemoryVT(), MemNode->getMemOperand());
16854 if (
N->getOperand(0) ==
LHS.getValue(1))
16855 InChain =
LHS.getOperand(0);
16867 DAG.
getRegister(PPC::CR0, MVT::i32),
N->getOperand(4),
16873 assert(isDot &&
"Can't compare against a vector result!");
16875 if (
SDValue Impossible = isImpossibleCompare())
16878 bool BranchOnWhenPredTrue = (
CC ==
ISD::SETEQ) ^ (Val == 0);
16885 EVT VTs[] = {
LHS.getOperand(2).getValueType(), MVT::Glue };
16890 switch (
LHS.getConstantOperandVal(1)) {
16909 N->getOperand(4), CompNode.
getValue(1));
16914 return DAGCombineBuildVector(
N, DCI);
16925 EVT VT =
N->getValueType(0);
16926 if (VT == MVT::i64 && !Subtarget.
isPPC64())
16928 if ((VT != MVT::i32 && VT != MVT::i64) ||
16936 unsigned Lg2 = (IsNegPow2 ? -Divisor : Divisor).
countr_zero();
16956 const APInt &DemandedElts,
16958 unsigned Depth)
const {
16960 switch (
Op.getOpcode()) {
16964 if (cast<VTSDNode>(
Op.getOperand(2))->getVT() == MVT::i16)
16965 Known.
Zero = 0xFFFF0000;
16969 switch (
Op.getConstantOperandVal(0)) {
16971 case Intrinsic::ppc_altivec_vcmpbfp_p:
16972 case Intrinsic::ppc_altivec_vcmpeqfp_p:
16973 case Intrinsic::ppc_altivec_vcmpequb_p:
16974 case Intrinsic::ppc_altivec_vcmpequh_p:
16975 case Intrinsic::ppc_altivec_vcmpequw_p:
16976 case Intrinsic::ppc_altivec_vcmpequd_p:
16977 case Intrinsic::ppc_altivec_vcmpequq_p:
16978 case Intrinsic::ppc_altivec_vcmpgefp_p:
16979 case Intrinsic::ppc_altivec_vcmpgtfp_p:
16980 case Intrinsic::ppc_altivec_vcmpgtsb_p:
16981 case Intrinsic::ppc_altivec_vcmpgtsh_p:
16982 case Intrinsic::ppc_altivec_vcmpgtsw_p:
16983 case Intrinsic::ppc_altivec_vcmpgtsd_p:
16984 case Intrinsic::ppc_altivec_vcmpgtsq_p:
16985 case Intrinsic::ppc_altivec_vcmpgtub_p:
16986 case Intrinsic::ppc_altivec_vcmpgtuh_p:
16987 case Intrinsic::ppc_altivec_vcmpgtuw_p:
16988 case Intrinsic::ppc_altivec_vcmpgtud_p:
16989 case Intrinsic::ppc_altivec_vcmpgtuq_p:
16996 switch (
Op.getConstantOperandVal(1)) {
16999 case Intrinsic::ppc_load2r:
17001 Known.
Zero = 0xFFFF0000;
17032 if (
ML->getLoopDepth() > 1 &&
ML->getSubLoops().empty())
17041 for (
auto I =
ML->block_begin(), IE =
ML->block_end();
I != IE; ++
I)
17043 LoopSize +=
TII->getInstSizeInBytes(J);
17048 if (LoopSize > 16 && LoopSize <= 32)
17062 if (Constraint.
size() == 1) {
17063 switch (Constraint[0]) {
17081 }
else if (Constraint ==
"wc") {
17083 }
else if (Constraint ==
"wa" || Constraint ==
"wd" ||
17084 Constraint ==
"wf" || Constraint ==
"ws" ||
17085 Constraint ==
"wi" || Constraint ==
"ww") {
17098 Value *CallOperandVal =
info.CallOperandVal;
17101 if (!CallOperandVal)
17108 else if ((
StringRef(constraint) ==
"wa" ||
17120 switch (*constraint) {
17150std::pair<unsigned, const TargetRegisterClass *>
17154 if (Constraint.
size() == 1) {
17156 switch (Constraint[0]) {
17158 if (VT == MVT::i64 && Subtarget.
isPPC64())
17159 return std::make_pair(0U, &PPC::G8RC_NOX0RegClass);
17160 return std::make_pair(0U, &PPC::GPRC_NOR0RegClass);
17162 if (VT == MVT::i64 && Subtarget.
isPPC64())
17163 return std::make_pair(0U, &PPC::G8RCRegClass);
17164 return std::make_pair(0U, &PPC::GPRCRegClass);
17170 if (Subtarget.hasSPE()) {
17171 if (VT == MVT::f32 || VT == MVT::i32)
17172 return std::make_pair(0U, &PPC::GPRCRegClass);
17173 if (VT == MVT::f64 || VT == MVT::i64)
17174 return std::make_pair(0U, &PPC::SPERCRegClass);
17176 if (VT == MVT::f32 || VT == MVT::i32)
17177 return std::make_pair(0U, &PPC::F4RCRegClass);
17178 if (VT == MVT::f64 || VT == MVT::i64)
17179 return std::make_pair(0U, &PPC::F8RCRegClass);
17183 if (Subtarget.hasAltivec() && VT.
isVector())
17184 return std::make_pair(0U, &PPC::VRRCRegClass);
17185 else if (Subtarget.hasVSX())
17187 return std::make_pair(0U, &PPC::VFRCRegClass);
17190 return std::make_pair(0U, &PPC::CRRCRegClass);
17192 }
else if (Constraint ==
"wc" && Subtarget.useCRBits()) {
17194 return std::make_pair(0U, &PPC::CRBITRCRegClass);
17195 }
else if ((Constraint ==
"wa" || Constraint ==
"wd" ||
17196 Constraint ==
"wf" || Constraint ==
"wi") &&
17197 Subtarget.hasVSX()) {
17201 return std::make_pair(0U, &PPC::VSRCRegClass);
17202 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17203 return std::make_pair(0U, &PPC::VSSRCRegClass);
17204 return std::make_pair(0U, &PPC::VSFRCRegClass);
17205 }
else if ((Constraint ==
"ws" || Constraint ==
"ww") && Subtarget.hasVSX()) {
17206 if (VT == MVT::f32 && Subtarget.hasP8Vector())
17207 return std::make_pair(0U, &PPC::VSSRCRegClass);
17209 return std::make_pair(0U, &PPC::VSFRCRegClass);
17210 }
else if (Constraint ==
"lr") {
17211 if (VT == MVT::i64)
17212 return std::make_pair(0U, &PPC::LR8RCRegClass);
17214 return std::make_pair(0U, &PPC::LRRCRegClass);
17219 if (Constraint[0] ==
'{' && Constraint[Constraint.
size() - 1] ==
'}') {
17223 if (Constraint.
size() > 3 && Constraint[1] ==
'v' && Constraint[2] ==
's') {
17224 int VSNum = atoi(Constraint.
data() + 3);
17225 assert(VSNum >= 0 && VSNum <= 63 &&
17226 "Attempted to access a vsr out of range");
17228 return std::make_pair(PPC::VSL0 + VSNum, &PPC::VSRCRegClass);
17229 return std::make_pair(PPC::V0 + VSNum - 32, &PPC::VSRCRegClass);
17234 if (Constraint.
size() > 3 && Constraint[1] ==
'f') {
17235 int RegNum = atoi(Constraint.
data() + 2);
17236 if (RegNum > 31 || RegNum < 0)
17238 if (VT == MVT::f32 || VT == MVT::i32)
17239 return Subtarget.hasSPE()
17240 ? std::make_pair(PPC::R0 + RegNum, &PPC::GPRCRegClass)
17241 : std::make_pair(PPC::F0 + RegNum, &PPC::F4RCRegClass);
17242 if (VT == MVT::f64 || VT == MVT::i64)
17243 return Subtarget.hasSPE()
17244 ? std::make_pair(PPC::S0 + RegNum, &PPC::SPERCRegClass)
17245 : std::make_pair(PPC::F0 + RegNum, &PPC::F8RCRegClass);
17249 std::pair<unsigned, const TargetRegisterClass *> R =
17258 if (R.first && VT == MVT::i64 && Subtarget.
isPPC64() &&
17259 PPC::GPRCRegClass.contains(R.first))
17260 return std::make_pair(
TRI->getMatchingSuperReg(R.first,
17261 PPC::sub_32, &PPC::G8RCRegClass),
17262 &PPC::G8RCRegClass);
17265 if (!R.second &&
StringRef(
"{cc}").equals_insensitive(Constraint)) {
17266 R.first = PPC::CR0;
17267 R.second = &PPC::CRRCRegClass;
17271 if (Subtarget.
isAIXABI() && !TM.getAIXExtendedAltivecABI()) {
17272 if (((R.first >= PPC::V20 && R.first <= PPC::V31) ||
17273 (R.first >= PPC::VF20 && R.first <= PPC::VF31)) &&
17274 (R.second == &PPC::VSRCRegClass || R.second == &PPC::VSFRCRegClass))
17275 errs() <<
"warning: vector registers 20 to 32 are reserved in the "
17276 "default AIX AltiVec ABI and cannot be used\n";
17286 std::vector<SDValue> &Ops,
17291 if (Constraint.
size() > 1)
17294 char Letter = Constraint[0];
17309 EVT TCVT = MVT::i64;
17314 if (isInt<16>(
Value))
17318 if (isShiftedUInt<16, 16>(
Value))
17322 if (isShiftedInt<16, 16>(
Value))
17326 if (isUInt<16>(
Value))
17342 if (isInt<16>(-
Value))
17350 if (Result.getNode()) {
17351 Ops.push_back(Result);
17362 if (
I.getNumOperands() <= 1)
17364 if (!isa<ConstantSDNode>(Ops[1].
getNode()))
17366 auto IntrinsicID = Ops[1].getNode()->getAsZExtVal();
17367 if (IntrinsicID != Intrinsic::ppc_tdw && IntrinsicID != Intrinsic::ppc_tw &&
17368 IntrinsicID != Intrinsic::ppc_trapd && IntrinsicID != Intrinsic::ppc_trap)
17371 if (
MDNode *MDN =
I.getMetadata(LLVMContext::MD_annotation))
17399 switch (AM.
Scale) {
17430 unsigned Depth =
Op.getConstantOperandVal(0);
17454 SDValue RetAddrFI = getReturnAddrFrameIndex(DAG);
17462 unsigned Depth =
Op.getConstantOperandVal(0);
17469 bool isPPC64 = PtrVT == MVT::i64;
17475 FrameReg = isPPC64 ? PPC::X1 : PPC::R1;
17477 FrameReg = isPPC64 ? PPC::FP8 : PPC::FP;
17487#define GET_REGISTER_MATCHER
17488#include "PPCGenAsmMatcher.inc"
17492 bool IsPPC64 = Subtarget.
isPPC64();
17505 if ((IsPPC64 && Reg == PPC::R2) || Reg == PPC::R0)
17511 Reg = Reg.id() - PPC::R0 + PPC::X0;
17533 if (isa<JumpTableSDNode>(GA) || isa<BlockAddressSDNode>(GA))
17551 unsigned Intrinsic)
const {
17552 switch (Intrinsic) {
17553 case Intrinsic::ppc_atomicrmw_xchg_i128:
17554 case Intrinsic::ppc_atomicrmw_add_i128:
17555 case Intrinsic::ppc_atomicrmw_sub_i128:
17556 case Intrinsic::ppc_atomicrmw_nand_i128:
17557 case Intrinsic::ppc_atomicrmw_and_i128:
17558 case Intrinsic::ppc_atomicrmw_or_i128:
17559 case Intrinsic::ppc_atomicrmw_xor_i128:
17560 case Intrinsic::ppc_cmpxchg_i128:
17562 Info.memVT = MVT::i128;
17563 Info.ptrVal =
I.getArgOperand(0);
17569 case Intrinsic::ppc_atomic_load_i128:
17571 Info.memVT = MVT::i128;
17572 Info.ptrVal =
I.getArgOperand(0);
17577 case Intrinsic::ppc_atomic_store_i128:
17579 Info.memVT = MVT::i128;
17580 Info.ptrVal =
I.getArgOperand(2);
17585 case Intrinsic::ppc_altivec_lvx:
17586 case Intrinsic::ppc_altivec_lvxl:
17587 case Intrinsic::ppc_altivec_lvebx:
17588 case Intrinsic::ppc_altivec_lvehx:
17589 case Intrinsic::ppc_altivec_lvewx:
17590 case Intrinsic::ppc_vsx_lxvd2x:
17591 case Intrinsic::ppc_vsx_lxvw4x:
17592 case Intrinsic::ppc_vsx_lxvd2x_be:
17593 case Intrinsic::ppc_vsx_lxvw4x_be:
17594 case Intrinsic::ppc_vsx_lxvl:
17595 case Intrinsic::ppc_vsx_lxvll: {
17597 switch (Intrinsic) {
17598 case Intrinsic::ppc_altivec_lvebx:
17601 case Intrinsic::ppc_altivec_lvehx:
17604 case Intrinsic::ppc_altivec_lvewx:
17607 case Intrinsic::ppc_vsx_lxvd2x:
17608 case Intrinsic::ppc_vsx_lxvd2x_be:
17618 Info.ptrVal =
I.getArgOperand(0);
17625 case Intrinsic::ppc_altivec_stvx:
17626 case Intrinsic::ppc_altivec_stvxl:
17627 case Intrinsic::ppc_altivec_stvebx:
17628 case Intrinsic::ppc_altivec_stvehx:
17629 case Intrinsic::ppc_altivec_stvewx:
17630 case Intrinsic::ppc_vsx_stxvd2x:
17631 case Intrinsic::ppc_vsx_stxvw4x:
17632 case Intrinsic::ppc_vsx_stxvd2x_be:
17633 case Intrinsic::ppc_vsx_stxvw4x_be:
17634 case Intrinsic::ppc_vsx_stxvl:
17635 case Intrinsic::ppc_vsx_stxvll: {
17637 switch (Intrinsic) {
17638 case Intrinsic::ppc_altivec_stvebx:
17641 case Intrinsic::ppc_altivec_stvehx:
17644 case Intrinsic::ppc_altivec_stvewx:
17647 case Intrinsic::ppc_vsx_stxvd2x:
17648 case Intrinsic::ppc_vsx_stxvd2x_be:
17658 Info.ptrVal =
I.getArgOperand(1);
17665 case Intrinsic::ppc_stdcx:
17666 case Intrinsic::ppc_stwcx:
17667 case Intrinsic::ppc_sthcx:
17668 case Intrinsic::ppc_stbcx: {
17670 auto Alignment =
Align(8);
17671 switch (Intrinsic) {
17672 case Intrinsic::ppc_stdcx:
17675 case Intrinsic::ppc_stwcx:
17677 Alignment =
Align(4);
17679 case Intrinsic::ppc_sthcx:
17681 Alignment =
Align(2);
17683 case Intrinsic::ppc_stbcx:
17685 Alignment =
Align(1);
17690 Info.ptrVal =
I.getArgOperand(0);
17692 Info.align = Alignment;
17710 if (Subtarget.hasAltivec() &&
Op.size() >= 16) {
17711 if (
Op.isMemset() && Subtarget.hasVSX()) {
17716 if (TailSize > 2 && TailSize <= 4) {
17721 if (
Op.isAligned(
Align(16)) || Subtarget.hasP8Vector())
17740 return !(BitSize == 0 || BitSize > 64);
17748 return NumBits1 == 64 && NumBits2 == 32;
17756 return NumBits1 == 64 && NumBits2 == 32;
17762 if (
LoadSDNode *LD = dyn_cast<LoadSDNode>(Val)) {
17763 EVT MemVT = LD->getMemoryVT();
17764 if ((MemVT == MVT::i1 || MemVT == MVT::i8 || MemVT == MVT::i16 ||
17765 (Subtarget.
isPPC64() && MemVT == MVT::i32)) &&
17781 "invalid fpext types");
17783 if (DestVT == MVT::f128)
17789 return isInt<16>(Imm) || isUInt<16>(Imm);
17793 return isInt<16>(Imm) || isUInt<16>(Imm);
17798 unsigned *
Fast)
const {
17812 !Subtarget.allowsUnalignedFPAccess())
17816 if (Subtarget.hasVSX()) {
17817 if (VT != MVT::v2f64 && VT != MVT::v2i64 &&
17818 VT != MVT::v4f32 && VT != MVT::v4i32)
17825 if (VT == MVT::ppcf128)
17839 if (
auto *ConstNode = dyn_cast<ConstantSDNode>(
C.getNode())) {
17840 if (!ConstNode->getAPIntValue().isSignedIntN(64))
17848 int64_t Imm = ConstNode->getSExtValue();
17849 unsigned Shift = llvm::countr_zero<uint64_t>(Imm);
17851 if (isInt<16>(Imm))
17876 return Subtarget.hasP9Vector();
17884 if (!
I->hasOneUse())
17888 assert(
User &&
"A single use instruction with no uses.");
17890 switch (
I->getOpcode()) {
17891 case Instruction::FMul: {
17893 if (
User->getOpcode() != Instruction::FSub &&
17894 User->getOpcode() != Instruction::FAdd)
17907 case Instruction::Load: {
17920 if (
User->getOpcode() != Instruction::Store)
17940 static const MCPhysReg ScratchRegs[] = {
17941 PPC::X12, PPC::LR8, PPC::CTR8, 0
17944 return ScratchRegs;
17948 const Constant *PersonalityFn)
const {
17949 return Subtarget.
isPPC64() ? PPC::X3 : PPC::R3;
17953 const Constant *PersonalityFn)
const {
17954 return Subtarget.
isPPC64() ? PPC::X4 : PPC::R4;
17959 EVT VT ,
unsigned DefinedValues)
const {
17960 if (VT == MVT::v2i64)
17961 return Subtarget.hasDirectMove();
17963 if (Subtarget.hasVSX())
17997 bool LegalOps,
bool OptForSize,
17999 unsigned Depth)
const {
18003 unsigned Opc =
Op.getOpcode();
18004 EVT VT =
Op.getValueType();
18029 if (Flags.hasNoSignedZeros() ||
Options.NoSignedZerosFPMath) {
18033 N0Cost,
Depth + 1);
18037 N1Cost,
Depth + 1);
18039 if (NegN0 && N0Cost <= N1Cost) {
18040 Cost = std::min(N0Cost, N2Cost);
18041 return DAG.
getNode(Opc, Loc, VT, NegN0, N1, NegN2, Flags);
18042 }
else if (NegN1) {
18043 Cost = std::min(N1Cost, N2Cost);
18044 return DAG.
getNode(Opc, Loc, VT, N0, NegN1, NegN2, Flags);
18063 if (M.getStackProtectorGuard() ==
"tls" || Subtarget.
isTargetLinux())
18087 bool ForCodeSize)
const {
18088 if (!VT.
isSimple() || !Subtarget.hasVSX())
18098 if (Subtarget.hasPrefixInstrs() && Subtarget.hasP10Vector()) {
18103 APSInt IntResult(16,
false);
18108 if (IsExact && IntResult <= 15 && IntResult >= -16)
18110 return Imm.isZero();
18113 return Imm.isPosZero();
18125 unsigned Opcode =
N->getOpcode();
18126 unsigned TargetOpcode;
18145 if (Mask->getZExtValue() == OpSizeInBits - 1)
18151SDValue PPCTargetLowering::combineSHL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18157 if (!Subtarget.isISA3_0() || !Subtarget.
isPPC64() ||
18160 N->getValueType(0) != MVT::i64)
18175 ShiftBy = DCI.DAG.getConstant(CN1->
getZExtValue(),
DL, MVT::i32);
18181SDValue PPCTargetLowering::combineSRA(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18188SDValue PPCTargetLowering::combineSRL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18207 auto isZextOfCompareWithConstant = [](
SDValue Op) {
18209 Op.getValueType() != MVT::i64)
18213 if (Cmp.getOpcode() !=
ISD::SETCC || !Cmp.hasOneUse() ||
18214 Cmp.getOperand(0).getValueType() != MVT::i64)
18217 if (
auto *
Constant = dyn_cast<ConstantSDNode>(Cmp.getOperand(1))) {
18218 int64_t NegConstant = 0 -
Constant->getSExtValue();
18221 return isInt<16>(NegConstant);
18227 bool LHSHasPattern = isZextOfCompareWithConstant(
LHS);
18228 bool RHSHasPattern = isZextOfCompareWithConstant(
RHS);
18231 if (LHSHasPattern && !RHSHasPattern)
18233 else if (!LHSHasPattern && !RHSHasPattern)
18239 SDValue Z = Cmp.getOperand(0);
18240 auto *
Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
18241 int64_t NegConstant = 0 -
Constant->getSExtValue();
18243 switch(cast<CondCodeSDNode>(Cmp.getOperand(2))->get()) {
18254 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18269 SDValue AddOrZ = NegConstant != 0 ?
Add : Z;
18306 if (!GSDN || !ConstNode)
18313 if (!isInt<34>(NewOffset))
18326SDValue PPCTargetLowering::combineADD(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18346 DAGCombinerInfo &DCI)
const {
18348 if (Subtarget.useCRBits()) {
18350 if (
SDValue CRTruncValue = DAGCombineTruncBoolExt(
N, DCI))
18351 return CRTruncValue;
18358 if (Op0.
getValueType() != MVT::i128 ||
N->getValueType(0) != MVT::i64)
18361 int EltToExtract = DCI.DAG.getDataLayout().isBigEndian() ? 1 : 0;
18371 EltToExtract = EltToExtract ? 0 : 1;
18381 return DCI.DAG.getNode(
18383 DCI.DAG.getTargetConstant(EltToExtract, dl, MVT::i32));
18388SDValue PPCTargetLowering::combineMUL(
SDNode *
N, DAGCombinerInfo &DCI)
const {
18392 if (!ConstOpOrElement)
18400 auto IsProfitable = [
this](
bool IsNeg,
bool IsAddOne,
EVT VT) ->
bool {
18424 return IsAddOne && IsNeg ? VT.
isVector() :
true;
18428 EVT VT =
N->getValueType(0);
18435 if ((MulAmtAbs - 1).isPowerOf2()) {
18439 if (!IsProfitable(IsNeg,
true, VT))
18452 }
else if ((MulAmtAbs + 1).isPowerOf2()) {
18456 if (!IsProfitable(IsNeg,
false, VT))
18477 DAGCombinerInfo &DCI)
const {
18482 EVT VT =
N->getValueType(0);
18485 unsigned Opc =
N->getOpcode();
18487 bool LegalOps = !DCI.isBeforeLegalizeOps();
18495 if (!
Flags.hasNoSignedZeros() && !
Options.NoSignedZerosFPMath)
18511bool PPCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
18528 if (!Callee ||
Callee->isVarArg())
18541bool PPCTargetLowering::
18542isMaskAndCmp0FoldingBeneficial(
const Instruction &AndI)
const {
18545 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(Mask)) {
18547 if (CI->getBitWidth() > 64)
18549 int64_t ConstVal = CI->getZExtValue();
18550 return isUInt<16>(ConstVal) ||
18551 (isUInt<16>(ConstVal >> 16) && !(ConstVal & 0xFFFF));
18560PPC::AddrMode PPCTargetLowering::getAddrModeForFlags(
unsigned Flags)
const {
18566 if ((Flags & FlagSet) == FlagSet)
18569 if ((Flags & FlagSet) == FlagSet)
18572 if ((Flags & FlagSet) == FlagSet)
18575 if ((Flags & FlagSet) == FlagSet)
18596 if ((FrameIndexAlign % 4) != 0)
18597 FlagSet &= ~PPC::MOF_RPlusSImm16Mult4;
18598 if ((FrameIndexAlign % 16) != 0)
18599 FlagSet &= ~PPC::MOF_RPlusSImm16Mult16;
18603 if ((FrameIndexAlign % 4) == 0)
18605 if ((FrameIndexAlign % 16) == 0)
18618 auto SetAlignFlagsForImm = [&](
uint64_t Imm) {
18619 if ((Imm & 0x3) == 0)
18621 if ((Imm & 0xf) == 0)
18627 const APInt &ConstImm = CN->getAPIntValue();
18646 const APInt &ConstImm = CN->getAPIntValue();
18656 }
else if (
RHS.getOpcode() ==
PPCISD::Lo && !
RHS.getConstantOperandVal(1))
18668 isValidPCRelNode<ConstantPoolSDNode>(
N) ||
18669 isValidPCRelNode<GlobalAddressSDNode>(
N) ||
18670 isValidPCRelNode<JumpTableSDNode>(
N) ||
18671 isValidPCRelNode<BlockAddressSDNode>(
N));
18676unsigned PPCTargetLowering::computeMOFlags(
const SDNode *Parent,
SDValue N,
18681 if (!Subtarget.hasP9Vector())
18686 if (Subtarget.hasPrefixInstrs())
18689 if (Subtarget.hasSPE())
18698 unsigned ParentOp = Parent->
getOpcode();
18702 if ((
ID == Intrinsic::ppc_vsx_lxvp) || (
ID == Intrinsic::ppc_vsx_stxvp)) {
18703 SDValue IntrinOp = (
ID == Intrinsic::ppc_vsx_lxvp)
18714 if (
const LSBaseSDNode *LSB = dyn_cast<LSBaseSDNode>(Parent))
18715 if (LSB->isIndexed())
18720 const MemSDNode *MN = dyn_cast<MemSDNode>(Parent);
18721 assert(MN &&
"Parent should be a MemSDNode!");
18726 "Not expecting scalar integers larger than 16 bytes!");
18729 else if (
Size == 32)
18736 else if (
Size == 256) {
18737 assert(Subtarget.pairedVectorMemops() &&
18738 "256-bit vectors are only available when paired vector memops is "
18746 else if (MemVT == MVT::f128 || MemVT.
isVector())
18756 if (
const LoadSDNode *LN = dyn_cast<LoadSDNode>(Parent)) {
18777 FlagSet &= ~PPC::MOF_NoExt;
18782 bool IsNonP1034BitConst =
18786 IsNonP1034BitConst)
18799 int16_t ForceXFormImm = 0;
18802 Disp =
N.getOperand(0);
18803 Base =
N.getOperand(1);
18814 !
N.getOperand(1).hasOneUse() || !
N.getOperand(0).hasOneUse())) {
18815 Disp =
N.getOperand(0);
18816 Base =
N.getOperand(1);
18830 unsigned NumParts,
MVT PartVT, std::optional<CallingConv::ID>
CC)
const {
18836 if (PartVT == MVT::f64 &&
18837 (ValVT == MVT::i32 || ValVT == MVT::i16 || ValVT == MVT::i8)) {
18846SDValue PPCTargetLowering::lowerToLibCall(
const char *LibCallName,
SDValue Op,
18850 EVT RetVT =
Op.getValueType();
18858 EVT ArgVT =
N.getValueType();
18863 Entry.IsZExt = !Entry.IsSExt;
18864 Args.push_back(Entry);
18872 (
RetTy ==
F.getReturnType() ||
F.getReturnType()->isVoidTy());
18878 .setTailCall(isTailCall)
18885SDValue PPCTargetLowering::lowerLibCallBasedOnType(
18886 const char *LibCallFloatName,
const char *LibCallDoubleName,
SDValue Op,
18888 if (
Op.getValueType() == MVT::f32)
18889 return lowerToLibCall(LibCallFloatName,
Op, DAG);
18891 if (
Op.getValueType() == MVT::f64)
18892 return lowerToLibCall(LibCallDoubleName,
Op, DAG);
18897bool PPCTargetLowering::isLowringToMASSFiniteSafe(
SDValue Op)
const {
18899 return isLowringToMASSSafe(
Op) &&
Flags.hasNoSignedZeros() &&
18903bool PPCTargetLowering::isLowringToMASSSafe(
SDValue Op)
const {
18904 return Op.getNode()->getFlags().hasApproximateFuncs();
18907bool PPCTargetLowering::isScalarMASSConversionEnabled()
const {
18911SDValue PPCTargetLowering::lowerLibCallBase(
const char *LibCallDoubleName,
18912 const char *LibCallFloatName,
18913 const char *LibCallDoubleNameFinite,
18914 const char *LibCallFloatNameFinite,
18917 if (!isScalarMASSConversionEnabled() || !isLowringToMASSSafe(
Op))
18920 if (!isLowringToMASSFiniteSafe(
Op))
18921 return lowerLibCallBasedOnType(LibCallFloatName, LibCallDoubleName,
Op,
18924 return lowerLibCallBasedOnType(LibCallFloatNameFinite,
18925 LibCallDoubleNameFinite,
Op, DAG);
18929 return lowerLibCallBase(
"__xl_pow",
"__xl_powf",
"__xl_pow_finite",
18930 "__xl_powf_finite",
Op, DAG);
18934 return lowerLibCallBase(
"__xl_sin",
"__xl_sinf",
"__xl_sin_finite",
18935 "__xl_sinf_finite",
Op, DAG);
18939 return lowerLibCallBase(
"__xl_cos",
"__xl_cosf",
"__xl_cos_finite",
18940 "__xl_cosf_finite",
Op, DAG);
18944 return lowerLibCallBase(
"__xl_log",
"__xl_logf",
"__xl_log_finite",
18945 "__xl_logf_finite",
Op, DAG);
18949 return lowerLibCallBase(
"__xl_log10",
"__xl_log10f",
"__xl_log10_finite",
18950 "__xl_log10f_finite",
Op, DAG);
18954 return lowerLibCallBase(
"__xl_exp",
"__xl_expf",
"__xl_exp_finite",
18955 "__xl_expf_finite",
Op, DAG);
18962 if (!isa<FrameIndexSDNode>(
N))
18980 unsigned Flags = computeMOFlags(Parent,
N, DAG);
18992 "Must be using PC-Relative calls when a valid PC-Relative node is "
19022 Disp =
N.getOperand(1).getOperand(0);
19027 Base =
N.getOperand(0);
19034 auto *CN = cast<ConstantSDNode>(
N);
19035 EVT CNType = CN->getValueType(0);
19036 uint64_t CNImm = CN->getZExtValue();
19047 if ((CNType == MVT::i32 || isInt<32>(CNImm)) &&
19049 int32_t
Addr = (int32_t)CNImm;
19054 uint32_t LIS = CNType == MVT::i32 ? PPC::LIS : PPC::LIS8;
19070 unsigned Opcode =
N.getOpcode();
19078 Base =
N.getOperand(0);
19097 Base = FI ?
N :
N.getOperand(1);
19109 bool IsVarArg)
const {
19119 return Subtarget.
isPPC64() && Subtarget.hasQuadwordAtomics();
19155 return Intrinsic::ppc_atomicrmw_xchg_i128;
19157 return Intrinsic::ppc_atomicrmw_add_i128;
19159 return Intrinsic::ppc_atomicrmw_sub_i128;
19161 return Intrinsic::ppc_atomicrmw_and_i128;
19163 return Intrinsic::ppc_atomicrmw_or_i128;
19165 return Intrinsic::ppc_atomicrmw_xor_i128;
19167 return Intrinsic::ppc_atomicrmw_nand_i128;
19184 {AlignedAddr, IncrLo, IncrHi});
19190 Lo, Builder.
CreateShl(
Hi, ConstantInt::get(ValTy, 64)),
"val64");
19211 Builder.
CreateCall(IntCmpXchg, {AlignedAddr, CmpLo, CmpHi, NewLo, NewHi});
19218 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="")
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
BasicBlock * GetInsertBlock() const
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
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)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool checkConvertToNonDenormSingle(APFloat &ArgAPFloat)
void GetReturnInfo(CallingConv::ID CC, Type *ReturnType, AttributeList attr, SmallVectorImpl< ISD::OutputArg > &Outs, const TargetLowering &TLI, const DataLayout &DL)
Given an LLVM IR type and return type attributes, compute the return value EVTs and flags,...
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool CC_PPC32_SVR4_ByVal(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
bool isIntS16Immediate(SDNode *N, int16_t &Imm)
isIntS16Immediate - This method tests to see if the node is either a 32-bit or 64-bit immediate,...
bool CC_PPC32_SVR4_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
static bool isRunOfOnes64(uint64_t Val, unsigned &MB, unsigned &ME)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
unsigned M1(unsigned Val)
bool isReleaseOrStronger(AtomicOrdering AO)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool RetCC_PPC_Cold(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
bool convertToNonDenormSingle(APInt &ArgAPInt)
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
bool CC_PPC32_SVR4(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool CC_PPC64_ELF(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
bool RetCC_PPC(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Mod
The access may modify the value stored in memory.
bool isIntS34Immediate(SDNode *N, int64_t &Imm)
isIntS34Immediate - This method tests if value of node given can be accurately represented as a sign ...
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
@ Mul
Product of integers.
@ And
Bitwise or logical AND of integers.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
unsigned M0(unsigned Val)
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
bool isAcquireOrStronger(AtomicOrdering AO)
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
constexpr unsigned BitWidth
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
static const unsigned PerfectShuffleTable[6561+1]
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load,...
static const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & PPCDoubleDouble() LLVM_READNONE
static constexpr roundingMode rmTowardZero
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Represent subnormal handling kind for floating point instruction inputs and outputs.
EVT changeVectorElementTypeToInteger() const
Return a vector with the same number of elements as this vector, but with the element type converted ...
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, bool IsScalable=false)
Returns the EVT that represents a vector NumElements in length, where each element is of type VT.
bool bitsGT(EVT VT) const
Return true if this has more bits than VT.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
uint64_t getScalarSizeInBits() const
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth)
Returns the EVT that represents an integer with the given number of bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
bool isVector() const
Return true if this is a vector value type.
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
bool isExtended() const
Test if the given EVT is extended (as opposed to being simple).
bool isScalarInteger() const
Return true if this is an integer, but not a vector.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
EVT getHalfNumVectorElementsVT(LLVMContext &Context) const
bool isInteger() const
Return true if this is an integer or a vector integer type.
unsigned getByValSize() const
void setByValSize(unsigned S)
Align getNonZeroByValAlign() const
OutputArg - This struct carries flags and a value for a single outgoing (actual) argument or outgoing...
bool isConstant() const
Returns true if we know the value of all bits.
void resetAll()
Resets the known state of all bits.
const APInt & getConstant() const
Returns the value when all bits have a known value.
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
MachinePointerInfo getWithOffset(int64_t O) const
static MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Structure that collects some common arguments that get passed around between the functions for call l...
const CallingConv::ID CallConv
These are IR-level optimization flags that may be propagated to SDNodes.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
CallLoweringInfo & setIsPostTypeLegalization(bool Value=true)
CallLoweringInfo & setLibCallee(CallingConv::ID CC, Type *ResultType, SDValue Target, ArgListTy &&ArgsList)
SmallVector< ISD::InputArg, 32 > Ins
CallLoweringInfo & setZExtResult(bool Value=true)
CallLoweringInfo & setDebugLoc(const SDLoc &dl)
CallLoweringInfo & setSExtResult(bool Value=true)
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals
bool isBeforeLegalizeOps() const
bool isAfterLegalizeDAG() const
void AddToWorklist(SDNode *N)
bool isBeforeLegalize() const
SDValue CombineTo(SDNode *N, ArrayRef< SDValue > To, bool AddTo=true)